我正在尝试IDynamicMetaObjectProvider
为第二版 C# in Depth 提供一个简短的示例,但我遇到了问题。
我希望能够表达一个无效的电话,但我失败了。我确信这是可能的,因为如果我使用反射绑定器动态调用 void 方法,一切都很好。这是一个简短但完整的示例:
using System;
using System.Dynamic;
using System.Linq.Expressions;
class DynamicDemo : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression expression)
{
return new MetaDemo(expression, this);
}
public void TestMethod(string name)
{
Console.WriteLine(name);
}
}
class MetaDemo : DynamicMetaObject
{
internal MetaDemo(Expression expression, DynamicDemo demo)
: base(expression, BindingRestrictions.Empty, demo)
{
}
public override DynamicMetaObject BindInvokeMember
(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Expression self = this.Expression;
Expression target = Expression.Call
(Expression.Convert(self, typeof(DynamicDemo)),
typeof(DynamicDemo).GetMethod("TestMethod"),
Expression.Constant(binder.Name));
var restrictions = BindingRestrictions.GetTypeRestriction
(self, typeof(DynamicDemo));
return new DynamicMetaObject(target, restrictions);
}
}
class Test
{
public void Foo()
{
}
static void Main()
{
dynamic x = new Test();
x.Foo(); // Works fine!
x = new DynamicDemo();
x.Foo(); // Throws
}
}
这会引发异常:
未处理的异常:System.InvalidCastException:由具有类型“DynamicDemo”的对象为活页夹“Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder”生成的动态绑定的结果类型“System.Void”与结果类型“System.Void”不兼容。调用站点预期的对象'。
如果我将方法更改为返回对象并返回 null,它可以正常工作......但我不希望结果为 null,我希望它为 void。这适用于反射绑定器(参见 Main 中的第一个调用),但对于我的动态对象却失败了。我希望它像反射活页夹一样工作——调用方法很好,只要你不尝试使用结果。
我是否错过了一种可以用作目标的特定表达方式?