2016-03-29 53 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

另外相关:(http://stackoverflow.com/questions/1724919/understanding-covariance-and-contravariance-in-c-sharp-4-0)[以C#4.0了解协变和逆变] [了解C#中的协变和逆变接口](http://stackoverflow.com/questions/2719954/understanding-covariant-and-contravariant-interfaces-in-c-sharp),[为什么我不能指定一个列表一个列表?](http://stackoverflow.com/questions/4652858/why-cant-i-assign-a-listderived-to-a-listbase);还有其他一些。 – poke

+0

如果你已经知道什么是造成你的问题(协方差和逆变)的术语,那么请展示一些努力,并且看看你开始写这个问题时应该向你提出的许多*现有问题,以及表明你的问题确实是基于你在这些问题的帮助下已经获得的知识。 – poke

+0

完全读出我的问题......我已经承认它的协变和逆变。还提到我正在寻找一个快速帮助/解决方案,并会在这个主题上了解更多。 – sanoj

回答

0

ATableITable<ARow>;它不是ITable<IRow>。如果它,则可以添加实现IRow的任何行类型,但只能从ARow继承行类型。

如果ITable协变(即,如果它被定义为ITable<out T>可以治疗的ITable<ARow>作为ITable<IRow>,但out关键字指示T仅用作输出从属性和方法。由于你有没有协变一RowCollection<T>性质(因为它是从Collection<T>它采用T作为输入继承),你不能让ITable协变的。

尽管DataRows属性仅具有get访问器,但它只将引用设置为只读集合。您仍然可以将T添加到集合中,因此它不是协变的。您可以将声明的类型更改为IEnumerable<T>,以使集合从接口的角度为“只读”。

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

谢谢史丹利。我的期望是只读集合(获得),所以我已经相应地更改了代码。谢谢你的观点。 – sanoj