Область видимости лямбда-переменных - PullRequest
7 голосов
/ 28 июня 2010

Пример:

myObject.Stub(s => s.MyMethod(null)).IgnoreArguments().Return("bleh");

var s = "s";

Переменная «s» определена в лямбда-выражении, а другая переменная «s» - как локальная переменная в том же методе.Visual Studio говорит мне «конфликтующая переменная определена ниже», когда я наводю курсор на первые «s».Почему они противоречат друг другу;«s» в лямбда-выражении недоступно за пределами его заключительных скобок?

1 Ответ

8 голосов
/ 28 июня 2010

Они противоречат друг другу, потому что правило C # заключается в том, что любые два использования одного и того же простого имени нельзя использовать для ссылки на две разные вещи внутри блока, сразу же заключающего в себе любую из них. В вашем примере простое имя «s» используется для обозначения двух вещей внутри блока, содержащего объявление локальной переменной: это локальная переменная и лямбда-параметр. То, что , является незаконным. Я отмечаю, что полученное сообщение об ошибке говорит вам следующее:

A local variable named 's' cannot be declared in this scope because it
would give a different meaning to 's', which is already used in a 
'child' scope to denote something else

C # не позволяет иметь одно и то же простое имя, означающее две вещи в одном и том же блоке, потому что это делает код подверженным ошибкам, трудным для редактирования, трудным для чтения, трудным для рефакторинга и трудным для отладки. Лучше запретить эту плохую практику программирования, чем разрешить ее и рискнуть вызвать ошибки, потому что вы предполагали, что «s» означает одно и то же во всем блоке.

Когда код длиной всего две строки, легко вспомнить, что для s есть два разных значения, но когда он длиной в сотни строк, это не так просто.

Для получения дополнительной информации об этом правиле см .:

http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx

...