Dynamic オブジェクトを Ironpython に引き渡そうとしていますが、Ironpython が TryInvokeMember を呼び出していないようです。代わりに、TryGetMember を呼び出し、結果を呼び出すことができないというエラーを返します。
IronPython 2.7 と 2.6.10920 で試してみました
例コード:
動的オブジェクト:
class ExampleDynamicObject: DynamicObject {
public override bool TryGetMember(GetMemberBinder binder,
out object result) {
result = "TryGetMember";
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder,
object[] args,
out object result) {
result = "TryInvokeMember";
return true;
}
}
Mathode の呼び出し
static void Main(string[] args) {
dynamic example = new ExampleDynamicObject();
var program = @"test = example.Call2(2)";
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
scope.SetVariable("example", example);
var source = engine.CreateScriptSourceFromString(program,
SourceCodeKind.Statements);
source.Execute(scope);
Console.ReadKey();
}
これにより、TryGetMember メソッドが呼び出され、Microsoft.Scripting.ArgumentTypeException "str is not callable" がスローされます。
これは、'test'(1) のようなコードを実行するとスローされます。
そのため、Python はこれが関数呼び出しであることを認識せず、代わりにプロパティを呼び出すだけのようです。
しかし、C#から呼び出そうとすると
Console.WriteLine(example.Call);
Console.WriteLine("----------------------------");
Console.WriteLine(example.Call(1));
これはうまくいきます:
TryGetMember
-------------------
TryInvokeMember
これを修正する方法について誰か提案がありますか?
解決策: (編集: calledMethodeName はリストでなければなりません。そうしないと、ネストされたメソッドが機能しません)
ジェフに感謝します。
そのようなダイナミックを設計するとき:
List<string> calledMethodeNames = new List<string>();
public override bool TryGetMember(GetMemberBinder binder,
out object result)
{
calledMethodeNames.Add(binder.Name);
result = this;
return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
//calledMethodeNames last Element has stored the Name of the called methode (remeber to remove it)
result = "TryInvoke";
return true;
}
すべてが正常に機能しています。
手がかりは、オブジェクトが呼び出し可能であり、python が TryInvoke (TryInvokeMember ではない) を呼び出すよりも、オブジェクト自体をメンバーとして返すことです。
ただし、TryInvoke が呼び出されるのは、オブジェクトを返した後にオブジェクト自体が呼び出されるためです。そのため、InvokeBinder は呼び出されたメソッドの名前を知りません。だから私はそれを変数に格納します。