2016-03-29 2 views
0

СценарийНа ковариации и контрвариации

public interface IRow 
{ 
    int Id { get; set; } 
    string Name { get; set; } 
} 
public class ARow : IRow 
{ ... } 
public class BRow : IRow 
{ ... } 
public class RowCollection<T> : Collection<T> where T : IRow 
{ } 

public interface ITable<T> where T : IRow 
{ 
    RowCollection<T> DataRows { get; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

public class ATable : ITable<ARow> 
{ 
    public RowCollection<ARow> DataRows 
    { 
     get; 
     set; 
    } 
} 

public class BTable : ITable<BRow> 
{ 
    public RowCollection<BRow> DataRows 
    { 
     get; 
     set; 
    } 
} 

Когда я сделать что-то вроде этого

 List<ITable<IRow>> lt = new List<ITable<IRow>>(); 
     ITable<IRow> ads = new ATable(); 

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

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

Привет, Сан-

+0

также связаны: [Понимание ковариационной и контрвариацию в C# 4.0] (http://stackoverflow.com/questions/1724919/understanding-covariance-and-contravariance-in-c-sharp-4-0), [Понимание ковариантных и контравариантных интерфейсов в C#] (http://stackoverflow.com/questions/2719954/understanding-covariant-and-contravariant-interfaces-in-c-sharp), [Почему я не могу назначить List a Список ?] (http://stackoverflow.com/questions/4652858/why-cant-i-assign-a-listderived-to-a-listbase); и есть куча других. – poke

+0

Если вы уже знаете, что вызывает проблемы (ковариация и контравариантность), пожалуйста, проявите некоторые усилия и посмотрите на многие * существующие * вопросы, которые должны были быть предложены вам, когда вы начали писать этот вопрос, и что ваша проблема действительно основана на знаниях, которые вы уже приобрели с помощью этих вопросов. – poke

+0

полностью зачитывает мой вопрос ... я признал, что это связано с дисперсией и контравариантностью. Также упоминается, что я ищу краткую помощь/решение и узнаю больше на эту тему. – sanoj

ответ

0

ATable является ITable<ARow>; это НЕ ITable<IRow>. Если это были, вы можете добавить любой тип строки, который реализует IRow, но он может принимать только типы строк, которые наследуют от ARow.

Если ITable были ковариантны (т.е. если она была определена как ITable<out T> то вы могли лечить ITable<ARow> как ITable<IRow>, но out ключевое слово указывает на то, что T используется только в качестве выходов из свойств и методов. Так как у вас есть RowCollection<T> свойство, которое не кОВАРИАНТНОЙ (потому что он наследует от Collection<T>, который использует T в качестве входов), вы не можете сделать ITable ковариантны.

Несмотря на то, что свойство DataRows имеет только аксессуар get, это делает только ссылку коллекции, доступной только для чтения. Вы можете добавить T s в коллекцию, чтобы она не была ковариантной. Вы можете изменить объявленный тип на IEnumerable<T>, чтобы сделать коллекцию «только для чтения» с точки зрения интерфейса.

public interface ITable<out T> where T : IRow 
{ 
    IEnumerable<T> DataRows { get; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 
+0

Спасибо Стэнли. Я ожидаю, что это сборка readonly (get), поэтому я изменил код соответственно. Спасибо за ваши баллы. – sanoj

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