Я нашел это, но попытался использовать его и отказавший.
Как я могу создать объект с помощью отражений и сделать его быстро путем помещения его в делегата?
DynamicMethod dm = new DynamicMethod("MyCtor", t, new Type[] { });
var ctor = t.GetConstructor(new Type[] { });
ILGenerator ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Newobj, ctor);
ilgen.Emit(OpCodes.Ret);
var d = (Func)dm.CreateDelegate(t);
dm.Invoke(null, new object[] { });
Прежде, чем поместить его в deleage я пытался, по крайней мере, вызвать его и когда я сделал выше, я получаю ошибку
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Дополнительная информация: Исключение было выдано целью вызова.
Если я называю d () вместо этого, я получаю исключение
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Type must derive from Delegate.
Как я не помещаю конструктора параметрического усилителя в делегата и называю его?
почему он существует то.
Он существует для классов, в которых вы заботитесь об их жизни, в частности, когда класс переносит ресурс в ОС и вы хотите выпустить его немедленно. В противном случае потребуется дождаться завершения CLR (недетерминированного).
Примеры, дескрипторы файлов, подключения к БД, подключения к сокетам,....
-121--3832538-Специально для веб-разработки, приобретая навыки работы с C #, стало намного проще писать javascript (и делать сложные вещи с помощью jQuery), потому что синтаксис так похож.
-121--3926545- Если у вас есть доступ к .NET 3,5 (что предлагает использование Func < T >
), вы можете найти выражение Expression
проще, чем ILGenerator
:
class Foo { }
static void Main() {
Func<Foo> func = GetCtor<Foo>(); // cache this somewhere!
Foo foo = func();
}
static Func<T> GetCtor<T>() {
Type type = typeof(T);
Expression body = Expression.New(type);
return Expression.Lambda<Func<T>>(body).Compile();
}
Довольно легко расширить его для использования конкретного конструктора, передачи аргументов или добавления свойства постконструктора слепки, преобразования и т.д. (см. этот связанный ответ ). Если у вас есть конкретный сценарий, я с радостью добавлю пример.
Также обратите внимание, что следует кэшировать и повторно использовать любые такие конструкторы - в противном случае вы потеряете преимущество (т.е. не будете повторно создавать делегат для каждого вызова).
Попробуйте это -
Action myCtor = CreateCtor(t, Type.EmptyTypes, typeof(Action));
public static Delegate CreateCtor(Type type, Type[] parameterTypes, Type delegateType, string typeParameterName)
{
var ctorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameterTypes, null);
if (ctorInfo == null)
{
string parameterString = string.Empty;
if(parameterTypes.Length > 0)
{
string[] parameterStrings = new string[parameterTypes.Length];
for(int i = 0; i < parameterTypes.Length; ++i)
{
parameterStrings[i] = parameterTypes[i].ToString();
}
parameterString = string.Join(",", parameterStrings);
}
throw new ArgumentException(string.Format("Type '{0}' does not define .ctor({1}).", type, parameterString), typeParameterName);
}
bool isVisible = type.IsVisible && (ctorInfo.IsPublic && !ctorInfo.IsFamilyOrAssembly);
DynamicMethod dynamicCtor = new DynamicMethod(Guid.NewGuid().ToString("N"), type, parameterTypes, ctorInfo.Module, !isVisible);
var il = dynamicCtor.GetILGenerator();
for (int i = 0; i < parameterTypes.Length; ++i)
{
switch (i)
{
case 0: il.Emit(OpCodes.Ldarg_0); break;
case 1: il.Emit(OpCodes.Ldarg_1); break;
case 2: il.Emit(OpCodes.Ldarg_2); break;
case 3: il.Emit(OpCodes.Ldarg_3); break;
default: il.Emit(OpCodes.Ldarg, i); break;
}
}
il.Emit(OpCodes.Newobj, ctorInfo);
il.Emit(OpCodes.Ret);
return dynamicCtor.CreateDelegate(delegateType);
}
В конструкторе нет аргументов, чтобы вы не должны загружать аргументы в стеке ilgen.emit (OPCodes.ldarg_0)
:
class Program
{
static void Main()
{
var t = typeof(Program);
var dm = new DynamicMethod("MyCtor", t, new Type[0], t.Module);
var ctor = t.GetConstructor(new Type[0]);
ILGenerator ilgen = dm.GetILGenerator();
ilgen.Emit(OpCodes.Newobj, ctor);
ilgen.Emit(OpCodes.Ret);
var del = (Func<Program>)dm.CreateDelegate(typeof(Func<Program>));
var instance = del();
Console.WriteLine(instance);
}
}