2016-01-25 3 views
0

Я ошеломлен тем, что это даже не компилируется. Это тестовая программа проблемы, с которой я сталкиваюсь в службе WCF, которую я пишу (где в основном клиент отправляет wcf-службу список различных задач, я тогда обрабатываю серверную часть, представляющую список различных задач, и нужно каждый раз использовать разные методы для каждого).Метод Перегрузка с объектами, реализующими один и тот же интерфейс

ошибка

компиляции: не может конвертировать из 'UserQuery.IMyInterface' в '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(); 
} 
+0

Почему ваш основной класс должен быть снабжен функциями как для MyObj1, так и для MyObj2? Разве эти люди не справятся с этим? У вашего дизайна есть некоторые странные недостатки, которые мы не можем решить, вероятно, пока вы не скажете, зачем вам эти два метода, где они есть. – HimBromBeere

+0

Вы ошеломлены тем, что автоматическое преобразование типов из типа * меньше * в тип * больше *? С какого языка программирования вы пришли? Python? Objective-C? C# не является «истинным» языком ООП, он имеет много статических типов проверки. – Luaan

+0

@ Luaan> Когда вы думаете об этом статически, это имеет смысл. Я думал, что во время выполнения я увижу экземпляр объекта и запустим правильную перегрузку. Забыл, он будет связан статически. – ZARk

ответ

4

Вы должны expliciltely бросить obj в MyObj1 как компилятор не знает, что вы назначаете экземпляр этого класса до obj.

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

Фактический тип obj известен только во время выполнения.

Лучше appraoch бы два определения метода Process на самом интерфейсе:

IMyInterface { 
    public string Process(); 
} 

Теперь ваши два класса осуществить это путем:

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

Таким образом, вы даже не должны пройти, что экземпляр метода.

+0

Итак, мне нужно создать фабричный класс, чтобы моя служба могла вызвать правильный перегруженный метод? :( Невозможно было бы использовать какое-то отражение во время выполнения? – ZARk

+0

@ZARk вы можете передать тип 'interface' в качестве параметра и вызвать метод на этом экземпляре – Ric

+0

. Это новая динамика "keyword ' dynamic a = Convert.ChangeType (obj, obj.GetType()); var s = Process (a); ' – ZARk

0

Почему бы не использовать открытые дженерики с type constraints? Нет необходимости в литье, нет необходимости в заводских классах или что-то еще hacky.

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

Зов это как

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

по назначению.

+0

Вы можете опустить тип-contraint на 'IMyInterface', поскольку' MyObj1' уже реализует его. – HimBromBeere

+0

Он использует IMyInterface obj, а не var obj. :-) –

Смежные вопросы