1

我有一个混合 c# 对象,带有一些实例属性和方法,我将它传递给 IronPython。我想要的是从 Py 代码同步调度到 c# 成员,包括静态和动态。

我在 c# 对象上实现了 IDynamicMetaObjectProvider,我注意到当 Py 调用我的对象的静态方法时,以及在编译时与动态定义的实例方法时,从未使用过 BindInvokeMember 方法,但它始终被称为 BindGetMember 方法.

我有点迷茫,大概这件事做不到吧?

4

2 回答 2

0

IronPython 将始终使用BindGetMember然后调用结果,因为这就是 Python 的工作方式——从对象中获取属性,然后调用它。您的实现应该返回另一个具有您需要的参数的BindGetMember动态对象 implements 。BindInvokeMember

于 2013-10-17T15:18:38.430 回答
0

我也被这个卡住了一段时间。解决方案是实现 BindGetMember 并返回一个元对象,其表达式指向一个函数。此函数必须返回一个委托,然后使用参数调用该委托。所以根本不使用 BindInvokeMember。这对我有用。我的代码如下所示:

         public override DynamicMetaObject BindGetMember(GetMemberBinder aBinder)
    {
        var aMetaObject = this;
        var aIsMethod = aMetaObject.IsMethod(aBinder.Name, aBinder.IgnoreCase);
        if (aIsMethod)
        {
            var aRestrictions = BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType);
            var aThisExpression = Expression.Convert(this.Expression, this.LimitType);
            var aMethodInfo = typeof(CDynamicObjectScriptAdapter).GetMethod(CDynamicObjectScriptAdapter.GetDelegate_MethodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var aParameters = new Expression[] { Expression.Constant(aBinder) };
            var aCallExpression = Expression.Call(aThisExpression, aMethodInfo, aParameters);
            var aResult = new DynamicMetaObject(aCallExpression, aRestrictions);
            return aResult;
        }
        else
        {
            var aRestrictions = BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType);
            var aThisExpression = Expression.Convert(this.Expression, this.LimitType);
            var aMethodInfo = typeof(CDynamicObjectScriptAdapter).GetMethod(CDynamicObjectScriptAdapter.GetValue_MethodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var aParameters = new Expression[] { Expression.Constant(aBinder) };
            var aCallExpression = Expression.Call(aThisExpression, aMethodInfo, aParameters);
            var aResult = new DynamicMetaObject(aCallExpression, aRestrictions);
            return aResult;
        }
    }

    internal const string GetDelegate_MethodName = "GetDelegate";
    internal object GetDelegate(GetMemberBinder aBinder)
    {
        var aScriptAdapter = this;
        var aAdaptedObject = aScriptAdapter.AdaptedObject;
        var aClassInfo = aAdaptedObject.ClassInfo;
        var aIgnoreCase = aBinder.IgnoreCase;
        var aCaseSensitive = !aIgnoreCase;
        var aMethodInfoDic = aClassInfo.GetScriptMethodInfoDic(aCaseSensitive);
        var aName = aBinder.Name;
        var aScriptMethodInfo = aMethodInfoDic[aName];
        var aMethodInfo = aScriptMethodInfo.MethodInfo;
        var aDelegateType = aScriptMethodInfo.ScriptMethodAttribute.DelegateType;
        var aDelegate = aMethodInfo.CreateDelegate(aDelegateType, aAdaptedObject);
        return aDelegate;
    }
于 2015-10-21T17:10:22.343 回答