代码之家  ›  专栏  ›  技术社区  ›  James Newton-King dbc

在不引用Microsoft.csharp.dll的情况下调用IDynamicMetaObjectProvider的成员

  •  4
  • James Newton-King dbc  · 技术社区  · 14 年前

    我有一个动态值(idynamicMetabObjectProvider的实现),我想调用方法和属性。

    到目前为止,我发现的调用动态值成员的示例是使用microsoft.csharp.dll之外的类型,例如。

    IDynamicMetaObjectProvider x = GetDynamicValue();
    CallSite<Func<CallSite, object, object, object>> site = CallSite<Func<CallSite, object, object, object>>.Create(
                Binder.SetMember(
                    Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
                    "Foo",
                    null,
                    new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                )
            );
    site.Target(site, x, 42);
    

    我希望能够在不使用microsoft.csharp.dll的情况下调用IDynamicMetaObjectProvider的成员。请注意,我不是在讨论使用c_dynamic关键字来处理与c_相关的任何内容,而是直接使用idynamicMetaObjectProvider。

    还要注意,使用反射是行不通的。反射绕过动态调用绑定,只对底层类型执行反射。我需要一种可以与idynamicMetabObjectProvider的任何实现一起工作的技术。

    1 回复  |  直到 14 年前
        1
  •  3
  •   jbtule    14 年前

    你必须实现你自己的 CallSiteBinder 因为没有不可知论的语言。基本上,这个想法是活页夹处理从调用语言提供的信息之间的细微差别,以便在任何对象上选择要绑定到的正确成员,而不考虑语言。

    因为它不像CSharp绑定器不能绑定到Ironpython对象,所以根据库消费者的语言,使用不同绑定器的灵活性取决于您通过库提供的灵活性。在上面的例子中,如果您不允许库使用者更改任何绑定器参数,那么使用CSharp绑定器就可以了,如果您提供了更多,那么通过依赖注入或重载方法提供切换绑定器可能会很有用。

    但是,我认为,如果您只想传递一些绑定器参数,CSharpBinder就可以了,因为CSharp Binder为您提供了非常好的灵活性绑定方面的知识(除了不打算将绑定更改为不区分大小写),而且它确实是通用库中绑定器的最佳选择,因为它是e仅语言活页夹包含在.NET 4.0安装和Mono 2.8安装中的标准。