我收到错误:
名为's'的局部变量不能 在此范围内声明,因为它 会对's'赋予不同的含义, 已经在“孩子”中使用 范围表示别的东西。
static void Main(string[] args)
{
string s = "hello"; // Line 1
var test = new[] { "abd", "def" }.Select(s => s.StartsWith("a")); // Line 2
}
为什么?
我猜想第1行的's'会被'.Select(s => ..'第2行的'decleration)阴影但是 - 据我所知 - 事实并非如此。
PS我不确定是否用正确的术语标出 - 如果有更好的词/短语,请纠正我。
答案 0 :(得分:6)
出现错误的原因与普通代码块(如 if 语句或循环)相同,您无法声明与代码块外部名称相同的变量。
这与类变量和方法变量不同,您可以使用 this 关键字显式引用类变量。
我认为 this 关键字是关键,因为没有任何方法可以显式引用同一方法但在不同代码块中的变量。
答案 1 :(得分:3)
关键是你已经可以在lambda表达式中引用局部变量s
了 - 所以引入另一个名为s
的变量会非常混乱。 C#编译器正在帮助您避免编写不可读的代码。
规范可以允许“extra-local”变量只是隐藏本地变量,但我认为这不是一个好主意。
答案 2 :(得分:1)
声明string s = "hello";
在lambda表达式之外声明,因此可以在其中访问。因此,s => s.StartsWith("a")
的声明与lambda表达式之外的s
声明冲突,即编译器无法确定您在语句s
中引用的s.StartsWith("a")
要显示问题,请考虑以下代码:
static void Main(string[] args)
{
string s = "hello"; // Line 1
var test = new[] { "abd", "def" }.Select(x => x.StartsWith("a") && s.StartsWith("h")); // Line 2
}
如果数组中的字符串(由lambda中的true
表示)以“a”开头且字符串x
以“a”开头,则只会在选择中返回s
H”。
顺便说一下,你的陈述只会返回一个ICollection<bool>
而不是ICollection<string>
,如你所料......返回以“a”开头的字符串:
new[] { "abd", "def" }.Where(x => x.StartsWith("a"));