gpt4 book ai didi

c# - 如何处理 DynamicObject 中的通用方法调用?

转载 作者:太空狗 更新时间:2023-10-29 23:52:35 25 4
gpt4 key购买 nike

我正在尝试构建一个能够处理通用方法调用的 DynamicObject,但似乎需要的 API - 尽管存在于 RC versions of 4.0 Framework 中- 已在 RTM 中标记为内部(即,CSharpInvokeMemberBinder 现在是内部的)。此代码是否有适用于 4.0 RTM 的等效代码?

public class TransparentObject<T> : DynamicObject {
private readonly T target;

public TransparentObject(T target) {
this.target = target;
}

public override bool TryInvokeMember(
InvokeMemberBinder binder, object[] args, out object result) {
var csBinder = binder as CSharpInvokeMemberBinder;
var method = typeof(T).GetMethod(binder.Name, BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
if (method == null)
throw new MissingMemberException(string.Format(
"Method '{0}' not found for type '{1}'", binder.Name, typeof(T)));
if (csBinder.TypeArguments.Count > 0)
method = method.MakeGenericMethod(csBinder.TypeArguments.ToArray());
result = method.Invoke(target, args);
return true;
}
}

(代码取自 http://bugsquash.blogspot.com/2009/05/testing-private-methods-with-c-40.html )

我知道我可以在此处使用反射来获取泛型类型参数,但我正在寻找更好的解决方案 - 如果有的话。

最佳答案

我能猜到的最快的等价物:

    private static readonly Func<InvokeMemberBinder, IList<Type>> GetTypeArguments;

static TransparentObject()
{
var type = typeof(RuntimeBinderException).Assembly.GetTypes().Where(x => x.FullName == "Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder").Single();
var dynamicMethod = new DynamicMethod("@", typeof(IList<Type>), new[] { typeof(InvokeMemberBinder) }, true);
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, type);
il.Emit(OpCodes.Call, type.GetProperty("Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder.TypeArguments", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
il.Emit(OpCodes.Ret);
GetTypeArguments = (Func<InvokeMemberBinder, IList<Type>>)dynamicMethod.CreateDelegate(typeof(Func<InvokeMemberBinder, IList<Type>>));
}

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var method = typeof(T).GetMethod(binder.Name, BindingFlags.Public| BindingFlags.NonPublic | BindingFlags.Instance);
if (method == null) throw new MissingMemberException(string.Format("Method '{0}' not found for type '{1}'", binder.Name, typeof(T)));
var typeArguments = GetTypeArguments(binder);
if (typeArguments.Count > 0) method = method.MakeGenericMethod(typeArguments.ToArray());
result = method.Invoke(target, args);
return true;
}

关于c# - 如何处理 DynamicObject 中的通用方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6954069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com