Unë supozoj se normalisht do të bënit diçka të tillë si pjesë e një zbatimi në fabrikë, ku llojet aktuale nuk njihen në kohën e përpilimit...
Së pari, vini re se një qasje më e lehtë mund të jetë një hap fillestar pas krijimit, atëherë mund të përdorni gjenerikët:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() {
T t = new T();
t.Init(args);
return t;
}
Më pas mund të përdorni MakeGenericMethod
dhe/ose CreateDelegate
.
Përndryshe; ju mund ta bëni këtë me në fluturim me Expression
(3.5) ose DynamicMethod
(2.0).
Qasja Expression
është më e lehtë për tu koduar:
var param = Expression.Parameter(typeof(int), "val");
var ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
var lambda = Expression.Lambda<Func<int, Foo>>(
Expression.New(ctor, param), param);
var func = lambda.Compile();
Foo foo = func(123);
string s = foo.ToString(); // proof
ose (duke përdorur DynamicMethod
):
ConstructorInfo ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
DynamicMethod dm = new DynamicMethod("Create", typeof(Foo),
new Type[] { typeof(int) }, typeof(Foo), true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
Converter<int, Foo> func = (Converter<int, Foo>)
dm.CreateDelegate(typeof(Converter<int, Foo>));
Foo foo = func(123);
string s = foo.ToString(); // proof
21.10.2009
ConstructorInfo
!=MethodInfo
, prandaj një delegat nuk mund të krijohet nga njëConstructorInfo
(pasi nuk është një metodë). 21.10.2009public static <SELF> Create<SELF>(/* args */)
. Prandaj mund të thuashFunc<string, string, Foo> = Foo.CreateFoo
. 14.02.2012class SomeClass
, atëherë duhet të shtoni një metodë të tillë në përkufizimin e klasës, ose të shtoni një metodë shtesë në një klasë statike. Nuk po i shoh rrethanat në të cilat sugjerimi juaj do të ishte i preferueshëm sesa përgjigja e leppie, e cila thjesht funksionon, duke shfrytëzuar motorin e konkluzionit të përpiluesit. PërdorimiFoo.CreateFoo
jo mjaftueshëm më i lehtë seMake<Foo>
. 04.02.2017