除了非人类可读的代码之外,还有另一个理由不为函数中的每个变量使用 var 吗?我的意思是不使用 int、SqlCommand、string 而是使用 var 会影响性能吗?
5 回答
使用或不使用“var”不会改变程序的其他可观察特征,例如它的性能。
是否使用“var”的问题取决于它对人类读者和代码维护者的影响,而不是它对编译后的工件的影响。
看看这篇优秀的文章:https ://docs.microsoft.com/en-gb/archive/blogs/ericlippert/uses-and-misuses-of-implicit-typing
这绝对不是性能上的打击。var 实际上不是类型,而是代码中的占位符,这意味着“我不想写出这个变量的类型”。事实上,如果您将鼠标悬停在 Visual Studio 中的文本上,它会显示一个工具提示,指示您认为太长而无法编写的类型!
但是,严肃地说,当您从代码中清楚类型是什么时,您通常应该使用 var,这样其他人在阅读它时不会感到困惑。
是的,var
到处使用。
我爱var。它为我节省了大量的击键。它帮助我以“使用优先”的方式编写代码,并使重构更加强大。
类型的名称无关紧要。Intellisense 告诉我类型可以做什么,这才是最重要的。
即使我知道类型名称,如果智能感知被破坏也对我没有多大帮助,因为我不一定知道仅从类型名称中调用的特定方法或属性。
一些var
使事情变得更好的细节:
- 调用方法(不知道它返回什么 - 特别是如果它是泛型类型)
这个很大。我经常不记得方法返回什么,但我知道该方法的名称。不得不将返回类型从我的脑海中拉出来让我慢下来。我只是编写var
,用我的输入调用方法,然后智能感知告诉我返回类型是什么以及我可以用它做什么。
// Imagine a method that creates a return type that gets some generic type from the call arguments
Tuple<TA,TB,TC,TD,TE> Combine<TA,TB,TC,TD,TE>(TA a, TB b, TC c, TD d, TE e);
// GOOD: Call this with var
var combo = Combine( "Some text", 42, true, new Dictionary<int, List<string>>(), "Other text");
// BAD: Without var
Tuple<string, int, bool, Dictionary<int, List<string>>, string> combo = Combine( "Some text", 42, true, new Dictionary<int, List<string>>(), "Other text");
- 重构返回类型
如果我使用var
,编译器会立即告诉我该类型在哪里被滥用(也许新的返回类型没有相同的属性名称)。
如果我不使用var
,我只会收到关于未能分配类型的错误。然后,我必须将该类型更改为新类型(调用它的每个地方),然后我最终会收到错误使用该类型的警告。
- 专注于命名变量而不是重新键入类型名称。
var
是 C# 发生过的最好的事情之一。
// BAD: No var
Dictionary<int,List<Tuple<int,bool,string>>> ahhhhThatWasDifficult = new Dictionary<int,List<Tuple<int,bool,string>>>();
// GOOD: With var
// I can think of a good name before writing this complex type
var validNameCountDictionary = new Dictionary<int,List<Tuple<int,bool,string>>>();
如果我还没有说服你,那么如果你想使用,你别无选择:
- 匿名类型
- 林克
所以,为什么不一路走,var
到处使用。
我知道这很晦涩,但有时我什至会这样做,这样我就可以始终使用var
我的代码并保持一致的外观:
var number = (int?) null;
因为我喜欢var。
PS 我有点难过在 Typescript/ES6 中let
被替换var
,但是 Javasctipt var
!== C#var
当您没有在检索变量值的同时声明变量时,很少/偶尔会出现这种情况。所以var
不能在这些情况下有效地使用。
示例 - 调用仅基于传递给它的对象类型的方法。
Derived d = null; // there is nothing to infer the type from
var someInfo = GetInfo(d);
...
// Base is an ancestor of Derived
Info GetInfo(Base b)
{
if (b is Derived) return ...;
if (b is Derived2) return ...;
...
}
也许你也可以这样做:
var d = default(Derived);
或者
var d = (Derived)null;
但IMO也没有任何可读性。我不会仅仅为了使用而这样做var
。
它是关于implicit and explicit typing
。C#.NET 是一种类型化语言,这意味着您可以定义存储在内存中的数据类型。如果你不定义它,你会降低一些操作的安全性,所以你想尽可能多地显式键入。但是在某些情况下,类型从您的代码中非常明显,因此您可以将其留给编译器来确定变量应该是什么类型,即implicit typing
.
没有类型的一个问题是,在内存中,它本质上是一堆 1 和 0,这些数据可能意味着任何东西,所以如果你最初在位置 000001 处输入一个整数,然后尝试将其读取为 Cat(想象一下作为某种类型),那么您刚刚从记忆中读出的任何内容都没有多大意义。这就是发明类型系统的原因,它可以告诉您将哪些数据存储在哪里,并确保您以人类可以再次理解的方式读回数据,而对于机器而言,它并不真正归根结底,数据是什么。