如果需要,将派生类型的通用IList <t>转换为具有期望的面向对象设计的基本类型

时间:2015-11-08 11:34:56

标签: c# oop generics c#-4.0 design-patterns

我有这个代码,因为Covariance我有编译错误。 如何解决此问题,我需要SelectAll方法返回IList<Entity>

我希望我的一些实体继承一个Abstract类,而在其他类中,我可以使用抽象类来做事情。改变我的设计以实现这一目标的最佳方法是什么?

public interface IEntities
{    
    IList<IEntities> SelectAll();
}

public abstract class Entity : IEntities
{
    public abstract IList<IEntities> SelectAll();
}

public class Server : Entity
{
    public IList<Entity> SelectAll()
    {
        return new IList<Server>();   // Compile Error 
    }
}

2 个答案:

答案 0 :(得分:0)

您无法实例化接口(IList是一个接口)。

您必须实例化实现IList的内容,例如list或array。

像这样:

return new List<Server>();

或:

return new Server[] { };

外部可用的功能只是IList声明的功能,没有您实际实现的类型的额外成员。

答案 1 :(得分:0)

有关相关讨论,请参阅thisthisthis个帖子。 IList<T> 不是协变。

如您所见,这不起作用

var strings = new List<string> { "a", "b", "c" };
List<object> objects = strings; //compilation error

您的选择一览:

var strings = new List<string> { "a", "b", "c" };

List<object> objects1 = strings.ConvertAll(s => (object)s); //List<T> method
List<object> objects2 = strings.Cast<object>().ToList(); //IEnumerable extension
List<object> objects3 = strings.Select(s => (object)s).ToList(); //plain Linq

例如,使用stringobject作为派生和基类。

注意

虽然

允许这样做
IEnumerable<string> strings = new List<string> { "x", "y", "z" };
IEnumerable<object> objects = strings; //works

因为,IEnumerable<T>covariant,而且它实际上是IEnumerable<out T>