lambda表达式中的事件 – C#编译器错误?

lambda表达式中的事件 – C#编译器错误?,第1张

概述我正在使用羔羊表达式来允许事件以强类型的方式进行连接,但是在中间有一个听众.给出以下类 class Producer{ public event EventHandler MyEvent;}class Consumer{ public void MyHandler(object sender, EventArgs e) { /* ... */ }}class Lis 我正在使用羔羊表达式来允许事件以强类型的方式进行连接,但是在中间有一个听众.给出以下类
class Producer{    public event EventHandler MyEvent;}class Consumer{    public voID MyHandler(object sender,EventArgs e) { /* ... */ }}class Listener{    public static voID WireUp<TProducer,TConsumer>(        Expression<Action<TProducer,TConsumer>> expr) { /* ... */ }}

一个事件将被连线如下:

Listener.WireUp<Producer,Consumer>((p,c) => p.MyEvent += c.MyHandler);

但是这会给出一个编译错误

CS0832: An Expression tree may not contain an assignment operator

现在起初这似乎是合理的,特别是在reading the explanation about why expression trees cannot contain assignments之后.然而,尽管C#语法,=不是一个赋值,它是调用Producer :: add_MyEvent方法,正如我们从CIL看到的那样生成的我们只是正常连线事件:

L_0001: newobj instance voID LambdaEvents.Producer::.ctor()L_0007: newobj instance voID LambdaEvents.Consumer::.ctor()L_000f: ldftn instance voID LambdaEvents.Consumer::MyHandler(object,class [mscorlib]System.EventArgs)L_0015: newobj instance voID [mscorlib]System.EventHandler::.ctor(object,native int)L_001a: callvirt instance voID LambdaEvents.Producer::add_MyEvent(class [mscorlib]System.EventHandler)

所以它看起来像我这样的编译器错误,因为它抱怨分配不被允许,但是没有任何分配发生,只是一个方法调用.还是我错过了什么?

编辑:

请注意,问题是“这种行为是编译器错误吗?”.对不起,如果我不清楚我在问什么.

编辑2

在阅读Inferis的回答之后,他说“在这个时候,=被认为是分配”,这样做有一定的意义,因为在这一点上,编译器可能不知道它将会变成CIL.

但是我不允许写明确的方法调用表单:

Listener.WireUp<Producer,Consumer>(    (p,c) => p.add_MyEvent(new EventHandler(c.MyHandler)));

得到:

CS0571: ‘Producer.MyEvent.add’: cannot explicitly call operator or accessor

所以,我猜这个问题归结于C#事件背景下的实际意义.这是否意味着“调用此事件的添加方法”或是否意味着“以尚未定义的方式添加到此事件”.如果是前者,那么这似乎是一个编译器的BUG,而如果它是后者,那么它有点不直观,但可以说是不是一个BUG.思考?

解决方法 在规范7.16.3节中,=和 – =运算符称为“事件分配”,它肯定使其听起来像一个赋值运算符.事实上,它在7.16节(“Assignment operators”)中是一个很大的提示:)从这个角度来看,编译器错误是有道理的.

然而,我同意它是过分的限制,因为一个表达式树完全可以表示lambda表达式给出的功能.

我怀疑语言设计师为了“稍微限制更多,运算符描述更一致”的方法,而不用担心这样的情况.

总结

以上是内存溢出为你收集整理的lambda表达式中的事件 – C#编译器错误?全部内容,希望文章能够帮你解决lambda表达式中的事件 – C#编译器错误?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1261131.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-08
下一篇2022-06-08

发表评论

登录后才能评论

评论列表(0条)

    保存