创建泛型列表

时间:2012-10-10 19:37:09

标签: c# generics collections

我的实体有基类

public class Entity<T> where T : Entity<T>, new()
{
    public XElement ToXElement()
    {
    }
    public static T FromXElement(XElement x)
    {
    }
}

我必须使用这个奇怪的构造Entity<T> where T : Entity<T>,因为我希望静态方法FromXElement是强类型的 此外,我有一些实体,如

public class Category : Entity<Category>
{
}
public class Collection : Entity<Collection>
{
}

如何使用基类创建我的实体的通用列表?

var list = new List<Entity<?>>();
list.Add(new Category());
list.Add(new Collection());

5 个答案:

答案 0 :(得分:4)

您不能使用该定义。没有&#34;共同基类&#34;在CategoryCollection之间(当然不是object)。

如果 ,请说明Entity<T>是否定义为:

public class Entity
{
}

public class Entity<T> : Entity where T : Entity<T>, new()
{
    public XElement ToXElement()
    {
    }
    public static T FromXElement(XElement x)
    {
    }
}

然后你可以做

var list = new List<Entity>();
list.Add(new Category());
list.Add(new Collection());

但是那会买什么?

答案 1 :(得分:1)

创建标记界面:

public interface IAmAGenericEntity { }

public class Entity<T> where T : IAmAGenericEntity, new()
// ...

public class Category : Entity<T>, IAmAGenericEntity
// ....

var list = new List<IAmAGenericEntity>();
// ...

答案 2 :(得分:1)

由于abstract上缺少Entity标记,我认为To / FromXElement使用反射,并且应该适用于Entity的任何子类型。我建议您按如下方式构建类:

public class Entity
{
    public XElement ToXElement() { ... }

    protected static T FromXElement<T>(XElement x)
        where T : Entity
    {
        ...
    }
}

public class Category : Entity
{
    public static Category : FromXElement(XElement x)
    {
        return FromXElement<Category>(x);
    }
}

“样板”是最小的,并且它不需要您创造性地绕过类型系统。您不必担心缺乏共同基础或手动转换。如果您愿意,可以完全删除样板,只需直接从Entity构建对象:

public class Entity
{
    public XElement ToXElement() { ... }

    public static T FromXElement<T>(XElement x)
        where T : Entity
    {
        ...
    }
}

从本质上讲,你所做的是实现一个C#不直接支持的类型类。有很多方法可以解决这个缺点,但我经常发现它们比它们的价值更麻烦,特别是在涉及静态方法时。如果C#支持静态扩展方法,那将很简单,但它不会。

答案 3 :(得分:0)

您可以将非泛型类定义为所有实体类的基类

public class Entity
{
}

并使实体继承实体

public class Entity<T> : Entity where T : Entity<T>, new()
{
}

现在您可以创建实体列表:

var list = new List<Entity>();

答案 4 :(得分:0)

您可以通过添加类的非泛型版本来解决此问题

class Entity
{
  // methods

  public T As<T>() 
  { 
    if (this is T) return (T)this;
    throw new InvalidCastException();
  }
}

class Entity<T> : Entity where T : Entity<T>, new()

class Cathegory : Entity<T> {}

然后创建基类列表:

var list = new List<Entity>()
list.Add(new Cathegory());

然后,如果要调用“特定于通用”操作,则需要调用“As”函数或简单地转换对象。