Есть, но это не простое решение. По сути, вы создаете динамический метод, а затем создаете из него делегата и используете его.
public static BaseBuilder Create(Type builderType, HttpContextBase httpContext, PathDataDictionary pathData)
{
if (!builderType.IsSubclassOf(baseBuilderType)) return null;
BuilderConstructorDelegate del;
if (builderConstructors.TryGetValue(builderType.FullName, out del))
return del(httpContext, pathData);
DynamicMethod dynamicMethod = new DynamicMethod("CreateBaseBuilderInstance", builderType, constructorMethodArgs, builderType);
ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Newobj, builderType.GetConstructor(constructorMethodArgs));
ilGenerator.Emit(OpCodes.Ret);
del = (BuilderConstructorDelegate)dynamicMethod.CreateDelegate(typeof(BuilderConstructorDelegate));
builderConstructors.TryAdd(builderType.FullName, del);
return del(httpContext, pathData);
}
Вот код, который я использую в Builder для ASP.NET
рамки в BuilderFactory.
Если в коде непонятно, вы должны знать, что после того, как у вас есть делегат, это удаление сохраняется в словаре с именем builderConstructors в приведенном выше коде. Поэтому в следующий раз фабрика просто использует делегата.
В этом конкретном случае классу требуется два параметра в своем конструкторе. Если вы используете конструктор по умолчанию для ваших классов, все немного проще.
Фабрика класса High Performance