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(奇怪的重复模板模式)。基类完成所有工作,类型信息通过继承从更具体的子类传递。埃里克·利珀特反对,但我不同意他的立场和推理。