Я пытаюсь привести краткий пример 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:
тип результата 'System.Void' из
динамическое связывание, создаваемое объектом
с типом «DynamicDemo» для связующего
'Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder'
несовместимо с типом результата «System.Object», ожидаемым
сайт вызова.
Если я изменю метод, чтобы вернуть объект и вернуть ноль, он работает нормально ... но я не хочу, чтобы результат был нулевым, я хочу, чтобы он был пустым. Это прекрасно работает для связывателя отражений (см. Первый вызов в Main), но не работает для моего динамического объекта. Я хочу, чтобы он работал как средство связывания отражений - метод можно вызывать, если вы не пытаетесь использовать результат.
Я пропустил какой-то конкретный тип выражения, которое могу использовать в качестве цели?