我创建了基本泛型类,没有只有一个方法的字段
public class Base<T> where T:class
{
public static T Create()
{
// create T somehow
}
}
public class Derived1 : Base<Derived1>
{
}
public class Derived2 : Base<Derived2>
{
}
public class Program
{
bool SomeFunction()
{
// Here I need reference to base class
Base baseref; // error here
switch(somecondition)
{
case 1:
baseref = Derived1.Create();
break;
case 2:
baseref = Derived1.Create();
break
}
// pass baseref somewhere
}
}
一个明显的选择是将基类转换为接口,但这是不可能的,因为接口不能包含静态方法。
我想我需要一些中间基类。请建议
答案 0 :(得分:6)
您必须从Base
类中删除通用参数,您可以将其移至Create
方法:
public class Base
{
public static T Create<T>() where T : class
{
return Activator.CreateInstance<T>();
}
}
public class Derived1 : Base
{
}
public class Derived2 : Base
{
}
答案 1 :(得分:3)
有了这句话,
public class Derived1 : Base<Derived1> {
根据基类,您以两种不同的方式使用Derived1。
你有效地告诉C#编译器Derived1:
这没有错(如果这是你真正想要的),但对于大多数编程场景来说这是不寻常的;你通常选择其中一个。但是,您的逻辑的好处是:您不仅通过继承具有Derived1的隐式实例(对于任何其他派生类也是如此),但基类可以还处理该相同派生的其他外部实例通过类型参数<T>
我在Base类中看到的一个问题是,当按预期使用工厂方法时,它会变成一种循环方案,因为,为了支持所有派生类,它需要支持class Base<T> where T:Base<T>
之类的东西。这几乎是不可能宣布的,因为你必须以循环的方式说:Base<Base<Base<!!!>>> baseref = null;
其中!!!代表无穷多个相同的数字。
一种可能的(强大的解决方案)是将Type参数从类移动到工厂Create方法,并将其用法限制为Base类类型,如下所示:
using System;
public abstract class Base
{
public static T Create<T>() where T : Base
{
return Activator.CreateInstance<T>();
}
}
注意:我已经创建了基类抽象,它将实例化限制为派生类型;但是你仍然可以使用基类引用(参见下面的switch
语句用法)。
这些派生类仍然继承自base。
public class Derived1 : Base
{
}
public class Derived2 : Base
{
}
您的工厂方法仅限于创建派生类型的实例。逻辑已被交换,因此派生类型被赋予工厂方法而不是在其上调用工厂方法。
public class Program
{
bool SomeFunction()
{
Base baseref = null;
switch(DateTime.Now.Second)
{
case 1:
baseref = Base.Create<Derived1>(); // OK
break;
case 2:
baseref = Base.Create<Derived2>(); //OK
break;
case 60:
baseref = Base.Create<string>(); //COMPILE ERR - good because string is not a derived class
break;
}
// pass baseref somewhere
}
}
答案 2 :(得分:2)
public abstract class Base
{
}
public class Base<T> : Base where T : class
{
public static T Create()
{
// create T somehow
}
}
public class Derived1 : Base<Derived1> // also inherits non-generic Base type
{
}
public class Derived2 : Base<Derived2> // also inherits non-generic Base type
{
}
答案 3 :(得分:1)
如何创建接口并让抽象类实现接口?