我在C#中有一个类,其模板和静态方法类似于
class BClass<T>
{
public static BClass<T> Create()
{
return new BClass<T>();
}
}
由此我派生出一个类并为基类
指定一个模板参数class DClass : BClass<int> { }
当我尝试使用静态方法创建D
的实例时出现问题class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create();
}
}
给出编译器错误“无法将类型'Test.BClass&lt; int&gt;'隐式转换为'Test.DClass'。”
添加以下强制转换会导致运行时强制转换异常。
DClass d = (DClass)DClass.Create();
是否有任何succint方法允许静态方法创建派生类的实例?理想情况下,我想要相当于c ++ typedef,我不想要下面的语法(这确实有用)。
BClass<int> d = DClass.Create();
答案 0 :(得分:7)
您希望DClass
成为BClass<int>
的别名。但这不是你在这里所拥有的。您所拥有的是DClass
来自 BClass<int>
。因此,调用DClass.Create();
会创建一个BClass<int>
,不一个DClass
(反之亦然)。
这可能会更清楚。假设你有这个层次结构:
class Rectangle {
static Rectangle Create() {
return new Rectangle();
}
}
class Square : Rectangle { }
// code elsewhere
var shape = Square.Create(); // you might want this to return a square,
// but it's just going to return a rectangle
获得所需功能的一个选项可能是定义Create
方法,如下所示:
static TClass Create<TClass>() where TClass : BClass<T>, new() {
return new TClass();
}
// code elsewhere
var shape = DClass.Create<DClass>();
虽然这有点混乱(并且还要求你为DClass
编写无参数构造函数)。如果你已经开始使用Create
方法来实例化对象,可以考虑为它编写一个工厂类。
答案 1 :(得分:6)
是可能的,通过对类型本身进行类型引用。请注意,在.NET世界中,我们讨论的是泛型,而不是模板,它们的工作方式确实存在重大差异。
class BClass<T, TSelf> where TSelf: BClass<T, TSelf>, new() {
public static TSelf Create() {
return new TSelf();
}
}
class DClass: BClass<int, DClass> {}
class Program {
static void Main(string[] args) {
DClass d = DClass.Create();
}
}
答案 2 :(得分:1)
class BClass<T>
{
public static T1 Create<T1, T2>() where T1 : BClass<T2>, new()
{
return new T1();
}
}
class DClass : BClass<int> { }
class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create<DClass, int>();
}
}