6 c# reflection delegates reflection.emit
我发现了这个,但试图使用它并失败了.
如何使用反射创建对象并通过将其置于委托中来加快速度?
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<T>)dm.CreateDelegate(t);
dm.Invoke(null, new object[] { });
Run Code Online (Sandbox Code Playgroud)
在把它删除之前我试图至少调用它,当我在上面做的时候我得到了错误
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Run Code Online (Sandbox Code Playgroud)
附加信息:调用目标引发了异常.
如果我调用d()而不是我得到异常
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Type must derive from Delegate.
Run Code Online (Sandbox Code Playgroud)
如何将一个无参数构造函数放入委托并调用它?
Mar*_*ell 11
如果你有机会到.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();
}
Run Code Online (Sandbox Code Playgroud)
很容易扩展它以使用特定的构造函数,传递参数或添加post-constructor属性绑定; 演员,转换等(见相关答案).如果你有一个特定的场景,我会很乐意添加一个例子.
另请注意,您应该缓存并重用任何此类构造函数 - 否则您将失去优势(即不要重新创建每次调用的委托).
尝试这个 -
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4819 次 |
| 最近记录: |