- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图举一个简短的例子 IDynamicMetaObjectProvider
对于第二版 C# 深入研究,我遇到了问题。
我希望能够表达一个 void 调用,但我失败了。我确信这是可能的,因为如果我使用反射绑定(bind)器动态调用 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
}
}
这会引发异常:
Unhandled Exception: System.InvalidCastException: The result type 'System.Void' of the dynamic binding produced by the object with type 'DynamicDemo' for the binder 'Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder' is not compatible with the result type 'System.Object' expected by the call site.
如果我将方法更改为返回对象并返回 null,它可以正常工作...但我不希望结果为 null,我希望它为 void。这对于反射绑定(bind)器来说效果很好(请参阅 Main 中的第一个调用),但对于我的动态对象来说却失败了。我希望它像反射绑定(bind)器一样工作 - 调用该方法就可以,只要您不尝试使用结果即可。
我是否错过了可以用作目标的特定表达方式?
最佳答案
这类似于:
您确实需要匹配 ReturnType
属性指定的返回类型。对于所有标准二进制文件,这几乎被固定为对象或无效(对于删除操作)。如果您知道自己正在进行无效调用,我建议将其包装在:
Expression.Block(
call,
Expression.Default(typeof(object))
);
DLR 过去对于允许的内容相当宽松,并且会自动提供一些最少量的强制。我们放弃了它,因为我们不想提供一组对每种语言可能有意义或没有意义的约定。
听起来你想阻止:
dynamic x = obj.SomeMember();
没有办法做到这一点,总会返回一个值,用户可以尝试继续动态交互。
关于dynamic - 如何将 void 方法调用表示为 DynamicMetaObject.BindInvokeMember 的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1835912/
我试图举一个简短的例子 IDynamicMetaObjectProvider对于第二版 C# 深入研究,我遇到了问题。 我希望能够表达一个 void 调用,但我失败了。我确信这是可能的,因为如果我使用
我是一名优秀的程序员,十分优秀!