DLR の助けが必要です。IDynamicMetaObjectProvider と DynamicMetaObject を実装していますが、予期される戻り値の型を取得する際に問題が発生しています。メタオブジェクトで BindInvokeMember をオーバーライドしています。すべての引数の型を確認できますが、戻り値の型は確認できません。可能であれば、私がそれに到達する方法を知っている人はいますか?戻り値の型が動的であることは知っていますが、呼び出しているものが戻り値の型に依存している場合はどうでしょうか。消費者が期待している戻り値の型がわからない限り、DynamicMetaObject で実行するアクションはわかりません。
アップデート 2
あらゆる種類の作業を呼び出すため、実際のコードをここに貼り付けることはできません。サンプルの動的オブジェクト コードを以下に示します。
public class TestDynamicMetaObject : DynamicMetaObject
{
public TestDynamicMetaObject(Expression expression, object value)
: base (expression, BindingRestrictions.Empty, value)
{
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Delegate method = new Func<int>(Test);
return new DynamicMetaObject(
Expression.Call(method.Method),
BindingRestrictions.GetInstanceRestriction(Expression,Value),
Value
);
}
public static int Test()
{
return 10;
}
}
public class TestDynamicObject : IDynamicMetaObjectProvider
{
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
{
return new TestDynamicMetaObject(parameter, this);
}
}
使っているところはこちら。
static void Main(string[] args)
{
try
{
dynamic x = new TestDynamicObject();
int gg= x.Test();
Console.WriteLine(gg);
}
catch (Exception excep)
{
Console.WriteLine(excep);
}
Console.ReadLine();
}
コンパイラが作成するコードは次のとおりです。
private static void Main(string[] args)
{
try
{
object x = new TestDynamicObject();
if (<Main>o__SiteContainer0.<>p__Site1 == null)
{
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, object, int>>.Create(new CSharpConvertBinder(typeof(int), CSharpConversionKind.ImplicitConversion, false));
}
if (<Main>o__SiteContainer0.<>p__Site2 == null)
{
<Main>o__SiteContainer0.<>p__Site2 = CallSite<Func<CallSite, object, object>>.Create(new CSharpInvokeMemberBinder(CSharpCallFlags.None, "Test", typeof(Program), null, new CSharpArgumentInfo[] { new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
}
Console.WriteLine(<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, <Main>o__SiteContainer0.<>p__Site2.Target(<Main>o__SiteContainer0.<>p__Site2, x)));
}
catch (Exception excep)
{
Console.WriteLine(excep);
}
Console.ReadLine();
}