0

我试图使用搜索找到答案,但最终决定改为创建新问题。

我正在将 XML 序列化为动态类型,我做了所有事情,但现在我希望能够以类似于反射的方式访问成员。

在继承自 的类型中DynamicObject,我实现了TryGetMemeberTryGetIndex方法,因此我可以使用这种方式访问​​值。

XmlTextReader xmlReader = new XmlTextReader(memStr);
DynamicXMLObjectConverter converter = new DynamicXMLObjectConverter();
dynamic obj = converter.Deserialize(xmlReader, typeof(DynamicXMLObject));

string str = obj.dynamic_property;
string item = obj[0];

它就像一个魅力但是我想通过运行时编译器服务访问相同的成员。

要获得成员,我使用以下代码:

CallSiteBinder binder = Binder.GetMember(CSharpBinderFlags.None, "dynamic_property", typeof(MyDynamic), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
CallSite<Func<CallSite, object, object>> callsite = CallSite<Func<CallSite, object, object>>.Create(binder);
var obj = callsite.Target(callsite, source);

它可以工作,我可以访问任何动态类型的成员。对我来说接下来的事情是使用相同的方式访问索引器。我知道Binder支持GetIndex方法,所以在技术上它应该以相同的方式工作,GetMember但它没有。

有人可以帮助我并解释如何使用 访问索引器callsite吗?任何代码示例将不胜感激!

4

1 回答 1

1

为了正确调用 Target,您需要在 Binder.GetIndex 调用中再添加一个 CSharpArgumentInfo 参数。否则,它会因 ArgumentOutOfRangeException 而失败。

这是一个工作示例:

var binder = Binder.GetIndex(CSharpBinderFlags.None, typeof (SampleDynamicObject), new[]
{
    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) // this argument is required!
});
var callsite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
var obj = callsite.Target(callsite, sampleObject, 0); // 0 is an index
于 2013-10-02T22:08:21.317 回答