0

I'm stunned that this doesn't even compile. This is a test program of the issue i'm having in a WCF service i'm writing (where basically the client sends the wcf service a list of different tasks, i'm then server-side processing that list of different tasks, and need to run different methods for each obviously).

Compilation error : cannot convert from 'UserQuery.IMyInterface' to 'UserQuery.MyObj1'

public interface IMyInterface{};

public class MyObj1 : IMyInterface{};
public class MyObj2 : IMyInterface{};


public String Process(MyObj1 obj)
{
return "did one";
}
public String Process(MyObj2 obj)
{
return "did two";
}

void Main()
{

    IMyInterface obj = new MyObj1();
    var s = Process(obj);

    s.Dump();
}
4
  • Why sould your main-class be provided with functionality for both MyObj1 and MyObj2? Shouldn´t those handle this on their own? Your design has some strange flaws which we cannot solve probably as long as you do not say why you need these two methods where they are. Commented Jan 25, 2016 at 10:07
  • You're stunned that there is no automatic type conversion from a less specific type to a more specific type? What programming background do you come from? Python? Objective-C? C# isn't a "true" OOP language, it has a lot of static type checking. Commented Jan 25, 2016 at 10:52
  • @Luaan > When you think about it statically it makes sense indeed. Kept thinking at runtime i'd see the instanceof the object and run the correct overload. Forgot it would be linked statically. Commented Jan 25, 2016 at 14:29
  • @HimBromBeere > It's what i would have done normally. But those objects are DTO's defined in a common library. So it made more sense to code all the work in a helper class called in the WCF service. Since i have about 30 of those, encapsulating each dto in a new class with the process method seemed like a lot of plumbing :) Commented Jan 25, 2016 at 14:29

2 Answers 2

4

You have to expliciltely cast obj to MyObj1 as the compiler does not know that you assign an instance of that class to obj.

IMyInterface obj = new MyObj1();
var s = Process((MyObj1) obj);

The actual type of obj is only known at runtime.

A better appraoch would be two define the method Process on your interface itself:

IMyInterface {
    public string Process();
}

Now your two classes implement this by:

class MyObj1 : IMyInterface {
    public string Process() { return "did one" ; }
}

Thus you do not even have to pass that instance to the method.

Sign up to request clarification or add additional context in comments.

6 Comments

So i'll have to create a factory class so my service can call the correct overloaded method ? :( Would it not be possible to use some kind of run-time reflection ?
@ZARk you could pass the interface type as the parameter and call a method on that instance
solved it !! Used the new "dynamic" keyword dynamic a = Convert.ChangeType(obj, obj.GetType()); var s = Process(a);
Seems pretty cumbersome to make use of dynamic here the way you do IMO. I would not recommend it.
dotnetperls.com/dynamic: "The dynamic keyword influences compilation. A dynamic variable can have any type. Its type can change during runtime. The downside is that performance suffers and you lose compile-time checking." Perhaps is not the best solution.
|
0

Why not use open generics with type constraints? No need for casting, no need for factory classes or anything hacky.

public string Process<T>(T obj)
  where T : IMyInterface
{
    ...
}

Call it like

IMyInterface obj = new MyObj1();
var s = Process(obj);

as intended.

2 Comments

You can omit the type-contraint on IMyInterface as MyObj1 already implements it.
He uses IMyInterface obj, not var obj. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.