如何建立一个行为如此的工厂:
interface A {
}
class B: A {
string b;
public B(string b) { this.b = b; }
}
class Factory {
public static T create<T>(/*somehow pass constructor parameters*/) where T: A {
return new T(/*constructor parameters*/);
}
}
B test = Factory.create<B>("test");
我知道,我可以使用类构造函数,但这种模式可能有一些用途,我想知道这是否可行。
答案 0 :(得分:1)
你可以做到,但它不漂亮。
class Factory {
public static T Create<T>(params object[] parameters) where T : A {
return (T) Activator.CreateInstance(typeof(T), parameters);
}
}
虽然这看起来很有吸引力,但也有问题:
Activator.CreateInstance
相比,new
非常慢。您可以使用Type.GetConstructor()
直接获取构造函数,这稍快一点,但仍然很糟糕。这样的解决方案往往对自己的利益太聪明了。即使对于工厂,使用静态类型也会好得多。工厂的另一种替代方法是接受将根据需要生成实例的Func<T>
:
void needToUseAnAForSomething(Func<A> aCreator) {
...
A a = aCreator();
}
然后客户端代码可以执行以下操作:
needToUseAnAForSomething(() => new B("test"));
在这种情况下,当然,我们可以简单地直接传递实例,但在更复杂的情况下,这可以取代工厂构造。
答案 1 :(得分:0)
这可以通过反思来实现:
public static T Create<T> (object[] parameters) where T : class
{
Type[] parameterTypes = (parameters ?? Enumerable.Empty<object> ())
.Select (parameter => parameter.GetType ()).ToArray ();
ConstructorInfo ctor = type.GetConstructor (parameterTypes);
Debug.Assert (ctor != null);
T instance = ctor.Invoke (parameters) as T;
Debug.Assert (instance != null);
return instance;
}
您可以通过调用以下方法调用该方法:
B test = Factory.Create<B> (new object[]{"test"});
答案 2 :(得分:0)
你可以尝试这样的事情 -
public static object create<T>(string param) where T : A
{
Type type = typeof(T);
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(string) });
object instance = ctor.Invoke(new object[] { param });
return instance;
}