События в лямбда-выражениях - ошибка компилятора C#?

Не проверено, но это должно работать:

[record_created]   DATETIME default (dateadd(hour,-6,getdate()))
10
задан Greg Beech 19 February 2009 в 12:23
поделиться

5 ответов

В спецификации разделите 7.16.3, + = и - =, операторы называют "Присвоением события", которое, конечно, заставляет ее походить на оператор присваивания. Самое то, что это в разделе 7.16 ("Операторы присваивания"), является довольно большой подсказкой :) С той точки зрения ошибка компилятора имеет смысл.

Однако я соглашаюсь, что это чрезмерно строго, поскольку для дерева выражений совершенно возможно представить функциональность, данную лямбда-выражением.

Я подозреваю, что разработчики языка пошли для "немного более строгий, но более последовательный в подходе" описания оператора, за счет таких ситуаций, я боюсь.

5
ответ дан 4 December 2019 в 02:27
поделиться

+ = присвоение, независимо от того, что это делает (например, добавьте событие). С точки зрения синтаксического анализатора это - все еще присвоение.

Вы пробовали

Listener.WireUp<Producer, Consumer>((p, c) => { p.MyEvent += c.MyHandler; } );
1
ответ дан 4 December 2019 в 02:27
поделиться

На самом деле, насколько компилятор касается той точки, это - присвоение. + = оператор перегружается, но компилятор не заботится, о котором в он - точка. В конце концов, Вы генерируете выражение через лямбду (который, однажды будет скомпилирован в фактический код), и никакой реальный код.

Таким образом, то, что делает компилятор, скажите: создайте выражение в том, где Вы добавляете c.MyHandler к текущему значению p.MyEvent и сохраните возвращенное значение в p.MyEvent. И таким образом, Вы на самом деле делаете уроки, даже если в конце Вы не.

Существует ли причина, Вы хотите, чтобы метод WireUp взял выражение и не только Действие?

1
ответ дан 4 December 2019 в 02:27
поделиться

Почему Вы хотите использовать класс Выражения? Изменение Expression<Action<TProducer, TConsumer>> в Вашем коде только к Action<TProducer, TConsumer> и все должны работать, как Вы хотите. Что Вы делаете, здесь вынуждает компилятор рассматривать лямбда-выражение как дерево выражений, а не делегата, и дерево выражений действительно не может содержать такие присвоения (это рассматривают как присвоение, потому что Вы используете + = оператор, которому я верю). Теперь, лямбда-выражение может быть преобразовано в любую форму (как указано на [MSDN] [1]). Путем простого использования делегата (это - весь класс Действия), такие "присвоения" совершенно допустимы. Я, возможно, неправильно понял проблему здесь (возможно, существует определенная причина, почему необходимо использовать дерево выражений?), но действительно кажется, что решение - к счастью, это простое!

Править: Право, я понимаю Вашу проблему немного лучше теперь из комментария. Есть ли любая причина, Вы не можете просто передать p. MyEvent и c. MyHandler как аргументы методу WireUp и присоединению обработчик событий в рамках метода WireUp (мне это также кажется лучше с точки зрения дизайна)... разве, который не избавил бы от необходимости дерево выражений? Я думаю, что лучше при предотвращении деревьев выражений так или иначе поскольку они имеют тенденцию быть довольно медленными по сравнению с делегатами.

1
ответ дан 4 December 2019 в 02:27
поделиться

Я думаю, что проблема, это кроме Expression<TDelegate> объект, дерево выражений не со статическим контролем типов с точки зрения компилятора. MethodCallExpression и друзья не выставляют информацию о статическом контроле типов.

Даже при том, что компилятор знает все типы в выражении, эта информация выброшена при преобразовании лямбда-выражения в дерево выражений. (Взгляните на код, генерируют для деревьев выражений),

Я, тем не менее, рассмотрел бы представление этого к Microsoft.

0
ответ дан 4 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: