2013-09-29 4 views
4

Можно ли сделать следующий код в C#? Я компилирую схожие на Java.Ковариация общего класса

public interface IInterface 
{ 
    ... 
} 

public class Class1 : IInterface 
{ 
    ... 
} 

public abstract class Base<T> where T : IInterface 
{ 
    ... 
} 

public class Class2<T> : Base<T> where T : IInterface 
{ 
    ... 
} 

. 
. 
. 

public SomeMethod() 
{ 
    List<Base<IInterface>> list = new List<Base<IInterface>>(); 
    Class2<Class1> item = new Class2<Class1>(); 
    list.Add(item); // Compile error here 
} 
+0

возможно дубликат [Ковариационный в C# универсальный класс] (http://stackoverflow.com/questions/16317541/covariance-in-c-sharp-generic-class) – nawfal

ответ

0

вы не можете использовать родовыми как this.list типа IInterface но вы пытаетесь добавить тип Class1 в list.it должен быть следующим ..

 List<Base<Class1>> list = new List<Base<Class1>>(); 
     Class2<Class1> item = new Class2<Class1>(); 
     list.Add(item); 
+0

В списке только один пример. Рассмотрим следующее: public void SomeMethod() { Другой метод (новый класс2 ()); } общественного недействительного AnotherMethod (Base объект) { ... } – Bumbala

5

Нет, это не является законным в C#. C# 4 и выше поддерживают ковариацию и контравариантность общих интерфейсов и общих делегатов, когда они построены с использованием ссылочных типов. Так, например, IEnumerable<T> ковариантен, так что можно сказать:

List<Giraffe> giraffes = new List<Giraffe>() { ... }; 
IEnumerable<Animal> animals = giraffes; 

но не

List<Animal> animals = giraffes; 

Поскольку список животных может иметь тигра вставленной в него, но список жирафы не может.

Сделайте веб-поиск по ковариации и контравариантности на C#, и вы найдете много статей на нем.

+0

Из того, что я прочитал в следующей ссылке: http://msdn.microsoft.com/en-us/library/dd799517.aspx Только интерфейсы и делегаты могут быть ковариантными. Похоже, мне нужно найти другое решение. Спасибо, в любом случае. – Bumbala

3

Похоже, что .NET Framework 4.0 поддерживает ковариацию в общих интерфейсах и делегатах. Итак, мне удалось скомпилировать код, добавив общий интерфейс.

public interface IInterface 
{ 
    ... 
} 

public class Class1 : IInterface 
{ 
    ... 
} 

public interface IBase<out T> where T: IInterface 
{ 
    // Need to add out keyword for covariance. 
} 

public class Base<T> : IBase<T> where T : IInterface 
{ 
    ... 
} 

public class Class2<T> : Base<T> where T : IInterface 
{ 
    ... 
} 

. 
. 
. 

public SomeMethod() 
{ 
    List<IBase<IInterface>> list = new List<IBase<IInterface>>(); 
    Class2<Class1> item = new Class2<Class1>(); 
    list.Add(item); // No compile time error here. 
} 
Смежные вопросы