Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建泛型列表_C#_Generics_Collections - Fatal编程技术网

C# 创建泛型列表

C# 创建泛型列表,c#,generics,collections,C#,Generics,Collections,我有实体的基类 public class Entity<T> where T : Entity<T>, new() { public XElement ToXElement() { } public static T FromXElement(XElement x) { } } 公共类实体,其中T:Entity,new() { 公共元素() { } 公共静态T FromXElement(XElement x) { } }

我有实体的基类

public class Entity<T> where T : Entity<T>, new()
{
    public XElement ToXElement()
    {
    }
    public static T FromXElement(XElement x)
    {
    }
}
公共类实体,其中T:Entity,new()
{
公共元素()
{
}
公共静态T FromXElement(XElement x)
{
}
}
我必须使用这个奇怪的构造
实体,其中T:Entity
,因为我希望静态方法FromXElement是强类型的 还有,我有一些实体,像这样

public class Category : Entity<Category>
{
}
public class Collection : Entity<Collection>
{
}
公共类类别:实体
{
}
公共类集合:实体
{
}
如何使用基类创建实体的通用列表

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

var list=newlist您不能使用该定义。
类别
集合
之间没有“公共基类”(当然,除了
对象

如果有,比如说如果
实体
被定义为:

public class Entity
{
}

public class Entity<T> : Entity where T : Entity<T>, new()
{
    public XElement ToXElement()
    {
    }
    public static T FromXElement(XElement x)
    {
    }
}
公共类实体
{
}
公共类实体:实体,其中T:Entity,new()
{
公共元素()
{
}
公共静态T FromXElement(XElement x)
{
}
}
那你就可以做了

var list = new List<Entity>();
list.Add(new Category());
list.Add(new Collection());
var list=newlist();
添加(新类别());
添加(新集合());

但是这会给您带来什么呢?

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

公共类实体
{
}
并使实体继承实体

公共类实体:实体,其中T:Entity,new()
{
}
现在,您可以创建实体列表,如下所示:

var list=newlist();

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

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> {}
类实体
{
//方法
公共交通服务
{ 
如果(这是T)返回(T)这个;
抛出新的InvalidCastException();
}
}
类实体:实体,其中T:Entity,new()
类Cathegory:实体{}
然后创建基类的列表:

var list = new List<Entity>()
list.Add(new Cathegory());
var list=新列表()
添加(新Cathegory());

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

创建标记接口:

public interface IAmAGenericEntity { }

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

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

var list = new List<IAmAGenericEntity>();
// ...
公共接口IAmAGenericEntity{}
公共类实体,其中T:IAmAGenericEntity,new()
// ...
公共类类别:实体、IAmAGenericEntity
// ....
var list=新列表();
// ...

由于
实体
上缺少
摘要
标记,我假设
/
FromXElement
使用反射,并且应该适用于
实体
的任何子类型。我建议您按照以下方式组织课程:

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);
    }
}

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

您想实现什么?为什么在集合中需要这些不同的类型?类别和集合是。。。他们自己?@DanielPersson,我明白了,这叫OK。Thx:如果实体约束的唯一目的是访问FromXElement,则不需要实体约束。只需从实体(即Category:Entity{})派生,您可以通过Category.FromXElement(element)调用它,它将有一个CategoryI的强类型返回值需要在基类中使用FromXElement/ToXElement。这不是fit@Evgraf-那你就得投了。没有一个
FromXElement
方法是
Category
Collection
都实现的(因为它们有不同的返回类型)。
public interface IAmAGenericEntity { }

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

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

var list = new List<IAmAGenericEntity>();
// ...
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);
    }
}
public class Entity
{
    public XElement ToXElement() { ... }

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