gpt4 book ai didi

c# - 用 IronPython 对象替换 .NET 对象实例

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:49 25 4
gpt4 key购买 nike

我正在尝试执行以下操作:

  • 获取在 C# 中定义的对象的实例
    • 它实现了某个接口(interface)
    • 它是另一个 C# 类实例上的字段
  • 用记录方法调用的 IronPython 代理对象包装它
  • 将包装器放回原来的位置

这是一个展示我正在尝试做的事情的例子。实际上,IWoof 接口(interface)上有更多的方法。

C#类和接口(interface):

namespace Foo
{
public interface IWoof { string DoSomething(); }

public class Bar
{
public Bar() { Woof = new WoofImp(); }
public IWoof Woof { get; set; }
}

public class WoofImp : IWoof
{
public string DoSomething()
{
return "DoSomething executing in C#";
}
}

}

我想使用 bar.Woof 并将其替换为 IronPython 代理。我想通过 IronPython 脚本执行此操作。我尝试了各种方法。

第一次尝试:覆盖getattr

我这样定义了一个包装器:

class Wrapper(object):

def __init__(self, obj):
self._obj = obj

def __getattr__(self, name):
print '__getattr__ called'
if name == "DoSomething":
return self.__DoSomething
else:
return object.__getattr__(self, name)

def __DoSomething(self):
result = self._obj.DoSomething()
return result + " AND DoSomething executing in Python"

如您所料,这工作正常:

import Foo
bar = Foo.Bar()
woof = Wrapper(bar.Woof)
print woof.DoSomething()

> DoSomething executing in C# AND DoSomething executing in Python

但是,当我尝试用包装对象替换 bar.Woof 时,它不起作用:

bar.Woof = woof_wrapper

> TypeError: expected IWoof, got Object_1$1
> Microsoft.Scripting.ArgumentTypeException: expected IWoof, got Object_1$1
at CallSite.Target(Closure , CallSite , Object , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

第二次尝试:实现C#接口(interface)

显然我的包装器需要实现 IWoof 接口(interface),所以我试过了。

class Wrapper_IWoof(object, Foo.IWoof): # Inherits from IWoof
... etc

现在我可以添加包装器实例并尝试像这样调用它:

woof = Wrapper_IWoof(bar.Woof)
bar.Woof = woof
print bar.Woof.DoSomething()

但是我遇到了一个新问题:

> AttributeError: 'Wrapper_IWoof' object has no attribute 'DoSomething'
> System.MissingMemberException: 'Wrapper_IWoof' object has no attribute 'DoSomething'
at IronPython.Runtime.Operations.PythonOps.MissingInvokeMethodException(Object o, String name)
at IronPython.NewTypes.System.Object#IWoof_4$4.DoSomething()
at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

第三次和第四次尝试:动态代理

我也尝试按照这里描述的这种方法(并再次实现 IWoof): http://www.ronnie-midnight-oil.net/2008/11/checking-type-contract-from-ironpython.html然而,它们导致了与上述两次尝试相同的问题。

替代方案

解决相同问题的另一种方法是通过反射生成一个 python 类并使用它。我已经这样做了并且有效。这为我提供了如下 Jeff Hardy 所描述的显式函数声明。

但是,我真的很想知道为什么上面的尝试不起作用。我做错了什么或遗漏了什么吗?

最佳答案

我认为你使用 __getattr__ 把事情搞得太复杂了。尝试直接实现接口(interface):

class Wrapper_IWoof(object, Foo.IWoof):

def __init__(self, obj):
self._obj = obj

def DoSomething(self):
result = self._obj.DoSomething()
return result + " AND DoSomething executing in Python"

关于c# - 用 IronPython 对象替换 .NET 对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22377616/

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