C#:通用继承工厂

C#:通用继承工厂,c#,inheritance,C#,Inheritance,我有一个基类,它只接受一个泛型参数。然后我有几个从这个基类继承的类。子类是否有一种从基类到工厂的简单方法 范例 class BaseClass<T> { T Value {get; set;} string Name {get; set;} public static BaseClass<T> Factory(T Value) { return new BaseClass<T>(Value);

我有一个基类,它只接受一个泛型参数。然后我有几个从这个基类继承的类。子类是否有一种从基类到工厂的简单方法

范例

class BaseClass<T>
{
     T Value {get; set;}
     string Name {get; set;}

     public static BaseClass<T> Factory(T Value)
     {
        return new BaseClass<T>(Value); 
     }
}

class ChildClass : BaseClass<int>
{
     public void Test()
     {
         // I want this below to work
         // but Factory() returns a BaseClass
         ChildClass bs = ChildClass.Factory(10);
     }
}
类基类
{
T值{get;set;}
字符串名称{get;set;}
公共静态基类工厂(T值)
{
返回新的基类(值);
}
}
类ChildClass:BaseClass
{
公开无效测试()
{
//我希望下面这个能起作用
//但是Factory()返回一个基类
ChildClass bs=ChildClass.Factory(10);
}
}
我已经在代码中注明了我想做什么。我可以想出一种克服这种情况的方法,通过向基类或从基类转换为子类的子类添加隐式运算符

我也可以显式地将工厂添加到子类中,但这会破坏继承点


有更好、更标准的方法吗?

我会这样做:

class BaseClass<T, K> where K : BaseClass<T, K>, new()
{
    T Value { get; set; }
    string Name { get; set; }

    public static K Factory(T value)
    {
        return new K { Value = value };
    }
}

class ChildClass : BaseClass<int, ChildClass>
{
    public void Test()
    {
        ChildClass cs = Factory(10);
    }
}
class基类,其中K:BaseClass,new()
{
T值{get;set;}
字符串名称{get;set;}
公共静态K工厂(T值)
{
返回新的K{Value=Value};
}
}
类ChildClass:BaseClass
{
公开无效测试()
{
ChildClass cs=工厂(10);
}
}

回答你的问题有点困难,因为你已经描述了你想做什么,但没有描述为什么。所以我得试着猜你想要什么

我不会将工厂方法与另一个答案或你的问题放在同一个类中。您将如何处理这一次的继承?它适用于您拥有的两个级别。但是如果您想扩展
ChildClass
,该怎么办

相反,我将创建一个用于对象创建的通用工厂。实现它有一个围绕工厂接口的单例,以便能够轻松地扩展它或交换实现

class MyFactory
{
    private static IMyFactory _instance;
    public static void Assign(IMyFactory factory) { _instance = factory; }
    public static T Create<T>() { return _instance.Create<T>(); }
}

interface IMyFactory
{
    T Create<T>();
}
class MyFactoryImp : IMyFactory
{
    //do whatever needed in here
    public T Create<T>(){ return new T(); }
}


class BaseClass<T>
{
     T Value {get; set;}
     string Name {get; set;}
}

class ChildClass : BaseClass<int>
{
     public void Test()
     {
         ChildClass bs = MyFactory.Create<ChildClass>(10);
     }
}

// start with this, you can easily switch implementation
MyFactory.Assign(new MyFactoryImp());
类MyFactory
{
私有静态IMyFactory_实例;
公共静态void Assign(IMyFactory工厂){u实例=工厂;}
公共静态T Create(){return_instance.Create();}
}
接口工厂
{
T Create();
}
类myfactorymp:IMyFactory
{
//在这里做任何需要的事
public T Create(){return new T();}
}
类基类
{
T值{get;set;}
字符串名称{get;set;}
}
类ChildClass:BaseClass
{
公开无效测试()
{
ChildClass bs=MyFactory.Create(10);
}
}
//首先,您可以轻松地切换实现
赋值(新的myfactorymp());

另一个明显的答案是开始使用控制反转容器,例如autofac。

为什么不在
Test()的内部键入cast()
?我不希望类需要为功能进行强制转换。如果我要进行强制转换,我将使其成为隐式强制转换。
Factory()
应该是静态的吗?@Mark:可能。对不过我并不在乎,我不想让它妨碍更细致的回答。您的
工厂
方法被声明为实例方法,但被当作静态方法使用。它不会编译,因为编译器无法推断
子类
,更不用说您没有指定
基类
。在您的代码中,它应该是
BaseClass.Factory(10)
@Kobi:它确实可以编译。我总是在泛型继承层次结构中做这种事情。@siride-你是对的,我错过了
工厂
被继承的部分。哎呀(奇怪,我确实记得测试过它
:P
)。但它确实更改了类签名。。。不过,如果调用
ChildClass.Factory(1)
,它似乎工作得很好,所以可能没关系。这很神奇。我不在乎它会改变签名。我明天会把这个标记为已回答,我很好奇是否还有其他方法可以做到这一点。@Mike:这是一种CRTP(奇怪的重复模板模式)。基类完成所有工作,类型信息通过继承从更具体的子类传递。埃里克·利珀特反对,但我不同意他的立场和推理。