为什么没有编译器警告没有分配给变量

时间:2018-05-03 19:48:24

标签: c# linq

我们说我有一个名为names的列表:

List<string> names = new List<string> { "Mike", "Steve", "Alan", "John" };

现在,如果我在列表List<T>.Sort上使用names方法:

names.Sort();

列表names将被排序:

  

&#34; Alan&#34;,&#34; John&#34;,&#34; Mike&#34;,&#34; Steve&#34;

我们假设我在初始列表OrderBy上使用LINQ Sort而不是names

names.OrderBy(x => x);

初始列表names不会被排序:

  

&#34; Mike&#34;,&#34; Steve&#34;,&#34; Alan&#34;,&#34; John&#34;

我知道是否要使用LINQ names对列表OrderBy进行排序我必须将查询分配给变量:

var orderedNames = names.OrderBy(x => x); 

初始列表names保持未分类,但orderedNames将保留初始列表的已排序名称:

  

&#34; Alan&#34;,&#34; John&#34;,&#34; Mike&#34;,&#34; Steve&#34;

我很好奇为什么没有编译器警告没有分配给变量的LINQ查询,因为调用names.OrderBy(x => x);而不首先将它分配给变量是没用的。

2 个答案:

答案 0 :(得分:10)

  

为什么没有编译器警告没有分配给变量的LINQ查询

这是一个功能。默认情况下不存在功能,必须将其删除。需要考虑,设计,指定,实施,测试,记录和发送功能。

所有这些都需要发生才能让你拥有这个功能。他们都没有发生。因此,没有任何特征。

如果您想要实施此功能,请选择它。编译器是开源的。如果你想提倡其他人实施它,那就去吧;设计过程也是公开的。

如果你要实施它,那么当你在它上面时,你也可以在字符串上查找调用TrimToLower等内容的内容。从未使用过。

现在,请注意&#34;未分配给变量&#34;不够。例如:

names.OrderBy(whatever).ToList().ForEach(whatever);

不对变量赋予任何内容,但您不想对此发出警告。类似地

Foo(names.OrderBy(whatever))

通过调用分配给变量(参数),而不是赋值。

类似地

x = y ? names.OrderBy(whatever) : whatever;

不直接分配,但仍使用该值。 要非常小心。编译器已经有一个检测器可以正确地确定表达式是否用于其值,因此请研究。

现在,也许你的问题是&#34;什么是困难或其他反对&#39;做这样的功能?&#34;

问题始终是误报。误报是代码正常工作的场景,它可以像开发人员想要的那样工作,代码可以被读者理解,并且仍然会收到警告。最好的误报让开发人员烦恼,但情况变得更糟。误报可能会破坏对编译器的信任,并且可能导致人们将工作代码更改为不会发出警告的错误代码。

让我们来看一个微妙的案例。假设我们有这样可怕的东西:

giraffes.Select(g => { g.Feed(); return 1; }).ToList();

这是可怕的代码。但警告不得类似于&#34;包含查询的表达式语句无用&#34;,因为这是误报。用户正在做一些非常非常错误的事情,但他们进行无用的查询;这个查询提供了所有的长颈鹿。

这里的错误是编写一个仅对其副作用有用的查询。查询不应该有副作用,这是编写foreach(var g in giraffes) g.Feed();

的超级糟糕方式

警告必须不仅仅是准确 99.99%的时间,他们必须尽可能识别真正的问题。这是一个超级难题,编译团队已经有了足够的问题。

这里有一个教训,那就是:考虑一下在设计语言时你想要阻止的不良做法。 C#非常擅长防止C和C ++程序员陷入的许多经典坏习惯。 (还有一些Java程序员陷入其中)。但是,区分&#34;对价值有用&#34;和&#34;对副作用有用&#34;因为这种区别不是以编译器易于理解或开发人员表示的方式捕获的。有些语言非常擅长区分,就像CAML系列中的语言一样。

答案 1 :(得分:0)

  

调用names.OrderBy(x => x);而不先将其分配给变量是没用的。

仅仅因为某些东西是无用的并不意味着编译器会(或应该)拒绝它。

您不仅可以使用LINQ查询,还可以使用任何方法来证明您的观点。

就像你有一些列表一样,然后你做list.IndexOf(-1);。你没有将这个值存储在任何东西中,所以对于所有意图和目的来说它都是无用的,但它仍然是一个有效的陈述。