2013-03-27 4 views
0

EDIT: Может быть, это яснее, к формулировке пункта вопроса:Разница в типе возвращаемого значения

В каком-то общем интерфейсе IInterface<T>, я хочу, чтобы вернуть объект общего типа, где один аргументов типа должна быть реализация IInterface<T>.

public class OtherType<T> {} 
public interface IInterface<T> 
{ 
    OtherType<IInterface<T>> Operation(); 
} 
public class Impl : IInterface<int> 
{ 
    public OtherType<IInterface<int>> Operation() 
    { 
     return new OtherType<Impl>(); 
    } 
} 

С Impl реализует IInterface<int>, кажется разумным мне, что я мог бы использовать его таким образом. Тем не менее, мне кажется, я не могу, я получаю ошибку компилятора

Невозможно преобразовать выражение типа OtherType<Impl> к, чтобы возвращаемый тип OtherType<IInterface<int>>

+0

Не могли бы вы преобразовать свои ОЧЕНЬ длинные и запутанные имена классов в нечто вроде A, B, C и так далее? – Sebastian

+0

@CarlPett: Вы следили за превосходной блогой блога Эрика Липперта в Монадах? http://ericlippert.com/2013/02/21/monads-part-one/ Кажется, вы боретесь заново изобретать эту конструкцию и можете использовать некоторое представление об общем механизме. –

+0

@PieterGeerkens: У меня нет, спасибо за подсказку! Кажется, действительно интересно. У меня было только время, чтобы прочитать первые четыре части, но пока я не могу понять, как применить его здесь? – carlpett

ответ

1

Вопрос заключается в том, что OtherType<T> является класс и общие классы не позволяют со/контравариации в C#. Generic interfaces do, если типы out не отображаются ни в каких позициях ввода, а типы in не отображаются в каких-либо выходных позициях. В своем примере кода вы можете получить его для компиляции, введя дополнительный интерфейс, обозначенный как ковариант, а затем изменив тип возвращаемого значения.

public interface IOtherType<out T> {} // new 
public class OtherType<T> : IOtherType<T> { } 

public interface IInterface<T> 
{ 
    IOtherType<IInterface<T>> Operation(); // altered 
} 
public class Impl : IInterface<int> 
{ 
    public IOtherType<IInterface<int>> Operation() 
    { 
     return new OtherType<Impl>(); 
    } 
} 

ли это будет на самом деле подходит ваш случай использования с дополнительными определениями метода является то, что только вы можете знать, учитывая ограниченность о детализации в вашем фрагменте кода.

+0

Спасибо, я попробую это. Смешно о «ограниченной детали», хотя ... Моя первая формулировка включала в себя подробные сведения о точных типах, которые я использую, а затем меня избивали за слишком много нерелевантного контекста: P – carlpett

+0

Работал так, как я хотел, отлично! – carlpett

1

OtherType<IInterface<int>> не означает, что «орудия» - это своего рода средство «является введите OtherType с параметром Interface<int> универсального типа, но это не так, как вы говорите

Если вы хотите, чтобы убедиться, что возвращаемый тип реализующий IInterface<int> затем установить, что в качестве возвращаемого типа:.

public interface IInterface<T> 
{ 
    IInterface<T> Operation(); 
} 

public class Impl : IInterface<int> 
{ 
    public <IInterface<int>> Operation() 
    { 
     return new OtherType(); 
    } 
} 

где

public class OtherType : IInterface<int> 
{} 

Это означает, что вы можете вернуть любой тип, который реализует IInterface<int>.

В противном случае вы можете сделать его немного более ограничены по призванию использовать общий тип ограничения:

public interface IInterface<T> 
{ 
    TRet Operation<TRet>() where TRet : IInterface<T>; 
} 

public class Impl : IInterface<int> 
{ 
    public TRet Operation<TRet>() where TRet : IInterface<int> 
    { 
     return new OtherType(); 
    } 
} 

Это означает, что вы можете тягот операцию, чтобы вернуть конкретный класс, который в свою очередь реализовать IInterface<int>.

Это можно было бы назвать:

Impl i = new Impl(); 
OtherType x = i.Operation<OtherType>();