我试图实现抽象类的一些泛型方法,如下所示:
public abstract class MyAbstractClass : MyBaseObject {
public MyAbstractClass() : base() { } // there is a parameterless constructor...
}
public class MyList<T> where T : MyBaseObject, new() {
// a generic container that is designed for the base class
}
//--- some paint control of mine
public class PaintControl : IDisposable {
public void InitDrawItems(MyList<MyAbstractClass> items) {
// paint items => this is where the compilation error occurs...
}
}
我得到以下编译错误:
错误24 'MyAbstractClass‘必须是具有公共无参数构造函数的非抽象类型,以便将其用作泛型类型或方法'MyList’中的参数'T‘。
当然,我想使用抽象的MyAbstractClass类(它有几个子类相应地处理绘画)。有办法绕道吗?
编辑:,我确实做了类抽象,以确保孩子们确实实现了抽象方法。
发布于 2019-05-24 02:51:59
新()不允许抽象类和接口用作T
,因为它们是不可实例化的。new()
意味着泛型类型必须声明符合对象实例化条件的公共无参数构造函数。因此,在我看来,您有一个选项:删除new()
子句,如果您对泛型中使用MyBaseObject
派生的任何抽象类型表示满意的话。由于您的类确实是抽象的,并且是MyBaseObject
的子类,所以这会很好地工作。
发布于 2019-05-24 02:53:42
这是由属型差异引起的问题。声明具体类型实际上会在编译时创建一个新类型。类中的类型参数不能在类型之间隐式转换。MyList<MyBaseObject>
与MyList<MyConcreteObject>
之间没有遗传关系。
只允许对一般接口或委托进行转换。
有两种方法可以解决这个问题--使用一个接口而不是一个具体的类,例如:
class MyList<T>:IList<T> where T : MyBaseObject, new()
{
}
class PaintControl {
public void InitDrawItems<T>(IList<MyAbstractClass> items) //where T:MyAbstractClass,new()
{
//var anItem=new T();
}
}
或者使InitDrawItems
本身成为通用的:
public void InitDrawItems<T>(MyList<T> items) where T:MyAbstractClass,new()
{
// No compilation errors here
}
发布于 2019-05-24 02:50:59
您应该在new()
中删除T
类型的MyList
约束,因为它指定您只能使用可以初始化的类型--抽象类型不能使用。
您可以在这里查看更多详细信息:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint
https://stackoverflow.com/questions/56290807
复制相似问题