2009-12-29 5 views
3

Я имею следующую структуру класса:.net 4 дженерики вопрос

public class A : AInterface { } 
public interface AInterface { } 

public class B<T> : BInterface<T> where T : AInterface 
{ 
    public T Element { get; set; } 
} 
public interface BInterface<T> where T : AInterface 
{ 
    T Element { get; set; } 
} 

public class Y : B<A> { } 

public class Z<T> where T : BInterface<AInterface> {} 

public class Test 
{ 
    public Test() 
    { 
     Z<Y> z = new Z<Y>(); 
    } 
} 

Это дает мне скомпилировать Erorr в C# 4.0. Тип «Test.Y» не может использоваться как параметр типа «T» в общем типе или методе «Test.Z». Нет никакого неявного преобразования ссылок из «Test.Y» в «Test.BInterface».

Я, хотя ковариация в дженериках должна сделать эту работу? Любая помощь будет оценена.

ответ

4

Общие параметры в интерфейсах по умолчанию инвариантны, вам нужно явно указать, хотите ли вы, чтобы определенный общий параметр был ковариантным или контравариантным. В основном, в вашем примере вам нужно добавить «из» ключевое слово в объявлении интерфейса:

public interface BInterface<out T> where T : AInterface { } 

Вы можете найти более подробную информацию о создании вариантные интерфейсов на MSDN: Creating Variant Generic Interfaces (C# and Visual Basic).

+0

Спасибо, Александра. Это, безусловно, поможет, если T - возвращаемый параметр. В моем случае я пропустил важную деталь в B и BInterface: общественного класса B : BInterface где T: { -интерфейса общественности T Элемент {получить; задавать; } } открытый интерфейс BInterface где T: AInterface { T Элемент {get; задавать; } } выход не будет работать, так как T находится как внутри, так и снаружи. Какие-либо предложения? – roger

+0

Да, если у вас есть общее ограничение на параметр типа, вы не можете сделать его ковариантным. Это по дизайну. http://msdn.microsoft.com/en-us/library/dd469487(VS.100).aspx "В общем интерфейсе параметр типа может быть объявлен ковариантным, если он удовлетворяет следующим условиям: 1) Параметр типа используется только как возвращаемый тип методов интерфейса и не используется в качестве типа аргументов метода. 2) Параметр type не используется в качестве общего ограничения для методов интерфейса. " –

1

I отсутствует out ключевое слово. Попробуйте добавить его к строкам:

public interface BInterface<out T> where T : AInterface { } 
public class Z<out T> where T : BInterface<AInterface> {} 

Я не уверен, что это необходимо в обоих местах.

+0

Классы не могут быть вариантами, поэтому вы не можете добавить «out» или «in» для общих параметров в классах. –

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