C#相当于Java列表<;?扩展类>;
我有泛型类的基本结构C#相当于Java列表<;?扩展类>;,c#,generics,generic-collections,C#,Generics,Generic Collections,我有泛型类的基本结构 public class Parent<T> where T : Parent<T> { Action<T> Notify; } public class Child : Parent<Child> { } 公共类父级,其中T:Parent { 行动通知; } 公共类子级:父级 { } 我想要一个列表,这样子对象就可以放在那里了 List parents=newlist() 在java中,我只能编写List,您不能
public class Parent<T> where T : Parent<T>
{
Action<T> Notify;
}
public class Child : Parent<Child>
{
}
公共类父级,其中T:Parent
{
行动通知;
}
公共类子级:父级
{
}
我想要一个列表,这样子对象就可以放在那里了
List parents=newlist()代码>
在java中,我只能编写List,您不能做与java相同的事情,因为在java中,泛型使用类型擦除和中断方差。本质上,您的Java代码将所有内容都转换为列表
,并希望做到最好。List
优于List
的唯一原因是,在Java中并非所有东西都是对象
——在C#中,可以在列表
中放入整数。记住,列表
的性能比列表
好得多,如果你负担得起的话——这就是泛型最初被添加到C#的一个重要原因
C#比那要严格一点。您不能执行任何类似于newlist()
的操作来允许任何类型的父级
。如果您有更有限的需求,您可以改用变体接口,但由于明显的原因,List
无法使用
您唯一的实际选择是使基类非泛型。您列表的用户无论如何都不能事先知道有关t
的任何信息,因此Parent
界面中返回或获取t
的任何部分在不强制转换的情况下都不会有用(Java为您进行转换,但它仍然在转换——Java和C#的泛型都不能满足您的需要)
为了完整性起见,您可以通过C#的动态
获得与Java类似的行为。但我甚至不打算展示任何示例-动态
是一个有用的工具,但主要用于更多的动态类型问题。对于像这样简单的问题,它有点过头了,用编译时问题来交换运行时问题
一般来说,如果您曾经直接使用Parent
,那么它应该在泛型方法中—例如,一个扩展方法,它对所有父类都有一些公共功能。您不能实例化一个泛型类型,因为它没有C#中当时已知的所有类型参数。声明List Parent;
不编译,因为它需要类型参数
当你说,公共类Child:Parent
它继承了Parent
而不是Parent
所以List;
只接受子类的对象,而不接受父类的任何其他子类的对象
您仍然可以通过以下界面实现所需的功能:
公共类程序
{
公共静态void Main()
{
List parentList=新列表();
parentList.Add(newchild1());
parentList.Add(newchild2());
}
}
公共类父类
{ }
公共接口IParent
{ }
公共类Child1:父级,IParent
{ }
公共类Child2:父级,IParent
{ }
不,不是。我有编译错误Generic.List需要'1'类型的参数
(它是本地化的,但类似于此)由于类型参数,您必须声明它List
。该类型约束很难闻。您这样做是因为它看起来与Java中的类似,还是因为没有它您无法在C中完成所需的工作?为什么基类是泛型的?来自同一个类。类型约束使这不可能,因为se基类最终是不同的。C#具体化了泛型,而不是类型擦除。
public abstract class Parent
{
// The common methods
public abstract int Id { get; }
}
public abstract class Parent<TChild> : Parent, IEnumerable<TChild>
{
// The methods that are TChild-specific - if you don't need any of those, just drop
// this class, the non-generic one will work fine
private List<TChild> children;
public void Add(TChild child) => ...
public TChild this[int index] => ...
}
public class Child : Parent<TChild>
{
...
}
var list = new List<Parent>();
var children = list.OfType<Child>();
public class Program
{
public static void Main()
{
List<Parent<IParent>> parentList = new List<Parent<IParent>>();
parentList.Add(new Child1());
parentList.Add(new Child2());
}
}
public class Parent<T>
{ }
public interface IParent
{ }
public class Child1 : Parent<IParent>, IParent
{ }
public class Child2 : Parent<IParent>, IParent
{ }