在c#中使用var关键字

在与同事讨论了c# 3中var关键字的使用后,我想知道人们对通过var适当使用类型推断的看法是什么?

例如,我很懒地在有问题的情况下使用var,例如:-

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

var更合法的用法如下:-

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

有趣的是,LINQ似乎是一个灰色区域,例如:-

var results = from r in dataContext.SomeTable
select r; // Not *entirely clear* what results will be here.

结果很明显,因为它将是一个实现IEnumerable的类型,但它并不完全明显,与var声明一个新对象的方式相同。

当涉及到对象的LINQ时,情况就更糟了,例如:-

var results = from item in someList
where item != 3
select item;

这并不比等价的foreach(var item in someList){//…}相当于。

这里有一个关于类型安全的真正问题-例如,如果我们将查询的结果放在一个重载方法中,该方法接受IEnumerable<int>和IEnumerable< double>调用方可能会无意中传入错误的类型。

var 保持强类型,但问题是类型在定义中不立即显示是否危险,当重载意味着当你无意中将错误的类型传递给方法时,编译器可能不会发出错误时,这种情况会被放大。

145433 次浏览

我认为var的使用应该与明智选择的变量名称相结合。

我在foreach语句中使用var没有问题,前提是它不是这样的:

foreach (var c in list) { ... }

如果是这样的话:

foreach (var customer in list) { ... }

... 这样,阅读代码的人就更有可能理解什么是“列表”。如果您可以控制列表变量本身的名称,那就更好了。

这同样适用于其他情况。这是非常无用的:

var x = SaveFoo(foo);

... 但这是有道理的:

var saveSucceeded = SaveFoo(foo);

各有各的,我想。我发现自己这样做,简直是疯了:

var f = (float)3;

我需要一个12步的var程序。我叫Matt,我(ab)使用var。

在我们的办公室,我们的CTO已经明确禁止使用var关键字,原因与您所陈述的相同。

我个人认为var的使用只在new对象声明中有效,因为对象的类型在语句本身就很明显。

对于LINQ查询,您可以将结果解析为:

IEnumerable<TypeReturnedBySelectObject>
当我开始使用var关键字时,我也有同样的担忧 然而,随着时间的推移,我已经习惯了它,不打算回到显式变量类型。 Visual Studio的编译器\智能感知在使隐式类型变量的工作更容易方面做得非常好。< / p >

我认为遵循正确的命名约定可以帮助您更好地理解代码,而不是显式键入。

这似乎是类似于“我应该在变量名中使用前缀吗?”的问题 坚持使用好的变量名,让编译器考虑变量类型

有人不喜欢批评var..所有答案downmodded..哦. .

< p > @Jon Limjap: 我知道。:)我的意思是可读性被降级了,就像在VB6一样。我不喜欢依靠智能感知来确定给定变量的类型。我希望能够单独使用源代码来计算它

命名惯例也没用——我已经用好名字了。我们要回到前缀时代吗?

我认为VAR的关键是只在适当的地方使用它,即在Linq中做一些方便的事情(可能在其他情况下)。

如果你有得到了的类型,那么你应该使用它-不这样做是简单的懒惰(相反的创造性懒惰,通常被鼓励-优秀的程序员往往非常努力地工作,懒惰,可以被认为是源头的东西摆在第一个位置)。

全面禁止就像滥用这种结构一样糟糕,但确实需要一个合理的编码标准。

另一件要记住的事情是,它不是VB类型变量,因为它不能改变类型——它是一个强类型变量,它只是类型是推断出来的(这就是为什么有人会认为在foreach中使用它不是不合理的,但出于可读性和可维护性的原因,我不同意)。

我怀疑这个会一直持续下去(-:

梅菲

var很困难的一个具体情况是:离线代码审查,特别是在纸上完成的代码审查。

你不能依赖鼠标的移动。

我仍然认为var可以使代码在某些情况下更具可读性。如果我有一个带有Orders属性的Customer类,我想把它赋值给一个变量,我只需要这样做:

var orders = cust.Orders;

我不在乎顾客。Orders是IEnumerable<Order>ObservableCollection<Order>BindingList<Order> -我想要的只是将该列表保存在内存中,以便稍后遍历它或获取其计数或其他内容。

将上述声明与:

ObservableCollection<Order> orders = cust.Orders;

对我来说,类型名只是噪音。如果我回头决定改变客户的类型。顺序沿着轨道(比如从ObservableCollection<Order>IList<Order>),然后我也需要改变声明-如果我在第一个地方使用var,我就不必这样做。

@erlando,出于好奇,为什么你需要知道变量的类型看源代码?

在我的实践中,我发现变量类型只在我在代码中使用它的时候对我来说是重要的。

如果我试图在someVar上做一些不适当的操作,编译器很乐意给我一个错误\警告。

我真的不在乎someVar有什么类型,如果我理解了为什么,它在给定的上下文中被使用。

我广泛使用var。有人批评这降低了代码的可读性,但没有证据支持这种说法。

不可否认,这可能意味着我们不清楚我们正在处理的是哪种类型。那又怎样?这实际上是解耦设计的要点。当处理接口时,你强调对变量的类型感兴趣。var更进一步,没错,但我认为从可读性的角度来看,参数保持不变:程序员实际上不应该对变量的类型感兴趣,而应该对变量是什么感兴趣。这就是为什么微软也称类型推断为“鸭子类型”。

那么,当我使用var声明变量时,它会做什么呢?简单,智能感知让它做什么它就做什么。任何关于c#的推理都忽略了IDE,这是不现实的。实际上,每个c#代码都是在支持智能感知的IDE中编写的。

如果我正在使用var声明的变量,并且对变量的用途感到困惑,那么我的代码有根本性的问题。var不是原因,它只是使症状可见。不要责怪送信的人。

现在,c#团队发布了一个编码指南,声明var应该被用来捕获创建匿名类型的LINQ语句的结果(因为在这里,我们没有真正的var替代方案)。去他的。只要c#团队没有给我一个合理的论证,我就会忽略它,因为在我的专业和个人观点中,这纯粹是胡扯。(抱歉;我找不到相关指南的链接。)

实际上,有一些(表面上)关于为什么你不应该使用var很好的解释,但我仍然认为它们在很大程度上是错误的。以“可搜索性”为例:作者声称var使得搜索使用MyType的地方变得困难。正确的。接口也是如此。实际上,我为什么要知道类在哪里使用?我可能更感兴趣的是它是在哪里实例化的,这将仍然是可搜索的,因为它的构造函数必须在某处调用(即使这是间接完成的,类型名必须在某处提到)。

@aku:代码审查就是一个例子。另一个例子是重构场景。

基本上我不想用我的鼠标去打字。它可能不可用。

我不明白这有什么大不了的。

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

你仍然对“某事”有完全的智能感知,对于任何不明确的情况,你都有单元测试,对吗?(是吗?)

它不是varchar,也不是dim,当然也不是动态或弱类型。它像这样阻止疯狂的人:

List<somethinglongtypename> v = new List<somethinglongtypename>();

把这些杂乱的思想归纳为:

var v = new List<somethinglongtypename>();

不错,但不如:

v = List<somethinglongtypename>();

但这就是的作用。

@erlando,

谈到重构,通过将新类型的实例分配给一个变量而不是在多个地方更改它来更改变量类型似乎要容易得多,不是吗?

至于代码审查,我认为var关键字没有大问题。在代码审查期间,我更喜欢检查代码逻辑而不是变量类型。当然,在某些情况下,开发人员可能会使用不合适的类型,但我认为这种情况的数量是如此之少,它不会成为我停止使用var关键字的理由。

我重复一下我的问题。为什么变量类型对你重要吗?

这是个人品味的问题。当你习惯动态类型语言时,所有这些关于变量的类型的烦恼就消失了。也就是说,如果你开始喜欢他们(我不确定是不是每个人都可以,但我喜欢)。

c#的var非常酷,因为它看起来类似于动态类型,但实际上是静态类型——编译器强制正确使用。

变量的类型并不是那么重要(这在前面已经说过了)。从上下文(它与其他变量和方法的交互)和它的名称来看,它应该相对清晰——不要期望customerList包含int

我还在等着看我的老板对这件事的看法——我得到了一个全面的“允许”,可以在3.5中使用任何新的结构,但是我们将如何维护呢?

在你比较IEnumerable<int>IEnumerable<double>时,你不需要担心——如果你传递了错误的类型,你的代码无论如何都不会编译。

不需要担心类型安全,因为var动态的。这只是编译器的魔法,任何类型不安全的调用都会被捕获。

Var对于Linq来说是绝对需要的:

var anonEnumeration =
from post in AllPosts()
where post.Date > oldDate
let author = GetAuthor( post.AuthorId )
select new {
PostName = post.Name,
post.Date,
AuthorName = author.Name
};

现在在智能感知中查看anonEnumeration,它将出现类似IEnumerable<'a>的东西

foreach( var item in anonEnumeration )
{
//VS knows the type
item.PostName; //you'll get intellisense here


//you still have type safety
item.ItemId;   //will throw a compiler exception
}

c#编译器非常聪明——单独生成的anon类型如果它们的属性匹配,将具有相同的生成类型。

除此之外,只要你有智能感知,在上下文清晰的地方使用var是很有意义的。

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();


//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();


//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;

我在各处分割var,对我来说唯一有问题的地方是内部短类型,例如,我更喜欢int i = 3;而不是var i = 3;

@Keith -

在你的比较之间 IEnumerable< int>而且 IEnumerable< double>你不需要 担心——如果你传递了错误的类型

这并不完全正确——如果一个方法重载到IEnumerable<int>和IEnumerable< double>然后,它可能会将意想不到的推断类型(由于程序中的其他一些更改)无声地传递给错误的重载,从而导致不正确的行为。

我想问题是这种情况出现的可能性有多大!

我猜部分问题是var给给定的声明增加了多少混乱——如果不清楚某个东西是什么类型(尽管它是强类型的,编译器完全理解它是什么类型),有人可能会掩盖一个类型安全错误,或者至少需要更长的时间来理解一段代码。

我在以下情况下使用var:

  1. 当我不得不(结果是匿名的)
  2. 当类型与代码在同一行时,例如:

    var emp = new Employee();

很明显,我们需要一个Employee对象(因为我们正在创建一个新的Employee对象),那么如何呢

Employee emp = new Employee() any more obvious?

当类型无法推断时,我不使用var。

var emp = GetEmployee();

因为返回类型不是很明显(是在Employee对象上,还是在IEmployee对象上,还是在与Employee对象完全没有关系的对象上,等等?)

在转换到3.0和3.5框架之后,我了解了这个关键字,并决定尝试一下。在提交任何代码之前,我意识到它似乎是向后的,就像回到ASP语法一样。所以我决定戳一下高层,看看他们怎么想。

他们说去吧,我就用了。

也就是说,我避免在类型需要一些调查的地方使用它,就像这样:

var a = company.GetRecords();

现在它可能只是一个个人的事情,但我立即不能看,并确定如果它是一个记录对象的集合或一个字符串数组表示记录的名称。无论哪种情况,我认为显式声明在这种情况下是有用的。

我不得不同意马特·汉密尔顿

当使用好的变量名时,Var可以使您的代码更具可读性和可理解性。但是,如果使用不当,var也会使您的代码像Perl一样难以阅读和理解。

一个var的好的和坏的用法列表也不会有太大的帮助。这是一个常识问题。更大的问题是可读性和可写性。许多开发者并不关心他们的代码是否具有可读性。他们只是不想打那么多。就我个人而言,我是一个读,写,写的人。

Kronoz -在这种情况下(两者都重载)会有问题吗?如果你有两个不同类型的重载,本质上你会说任何一个都可以被传递,做同样的事情。

不应该有两个重载根据传递的类型执行完全不同的操作。

虽然在这种情况下您可能会感到困惑,但它仍然是完全类型安全的,只是有人调用了错误的方法。

我不明白为什么人们会这样开始辩论。它真的没有任何目的,而不是开始激烈的战争,然后结束,什么也得不到。现在,如果c#团队试图逐步淘汰一种风格,以支持另一种风格,我可以看到争论每种风格优点的理由。但既然两者都将保留在语言中,为什么不使用更喜欢的,让每个人都这样做呢?这就像使用每个人都喜欢的三元运算符:有些人喜欢它,有些人不喜欢。在一天结束的时候,这对编译器没有区别。

这就像和你的兄弟姐妹争论你最喜欢的父母是谁:除非他们离婚了,否则没关系!

静态类型是关于契约的,而不是源代码。这里的想法是需要将静态信息放在“应该”是一个小方法的单行上。一般指南建议每个方法不要超过25行。

如果一个方法足够大,以至于您无法跟踪该方法中的单个变量,那么您做错了其他事情,这将使任何对var的批评相形见绌。

实际上,var的一个重要论点是,它可以使重构更简单,因为您不再需要担心您的声明过于严格(例如,当您应该使用IList<>或IEnumerable<>时,您使用了List<>)。您仍然需要考虑新的方法签名,但至少不必返回并更改声明来匹配。

我发现使用var关键字实际上使代码更具可读性,因为你只是习惯于跳过'var'关键字。当您真的不关心具体类型是什么时,您不需要一直向下滚动来弄清楚代码在做什么。如果我真的需要知道下面的“item”是什么类型,我只需将鼠标悬停在它上面,Visual Studio就会告诉我。换句话说,我更愿意读书

foreach( var item in list ) { DoWork( item ); }

一遍又一遍地

foreach( KeyValuePair<string, double> entry in list ) { DoWork( Item ); }

当我试图消化代码时。我认为这在某种程度上可以归结为个人喜好。在这一点上,我将依赖常识——在重要的方面(安全性、数据库使用、日志记录等)保留强制标准。

出。

我们采用了“为人编写代码,而不是为机器编写代码”的理念,基于这样的假设:在维护模式中花费的时间要比在新的开发模式中花费的时间长好几倍。

对我来说,这就排除了编译器“知道”变量是什么类型的说法——当然,你不可能第一次就写出无效的代码,因为编译器会阻止你的代码编译,但是当下一个开发人员在6个月的时间里阅读代码时,他们需要能够推断出变量做得正确或不正确的地方,并快速确定问题的原因。

因此,

var something = SomeMethod();

在我们的编码标准中是不合法的,但在我们的团队中鼓励这样做,因为它增加了可读性:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
DoWork( item );
}

来自c#团队的高级软件设计工程师Eric Lippert:

为什么引入var关键字?

有两个原因,一个是 今天已经存在,将来还会出现 在3.0 . < / p > 第一个原因是这段代码是 非常丑,因为所有的 冗余:< / p >

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

这是一个简单的例子-我已经 写的更糟。任何时候你都可以 要输入两次完全相同的东西, 这是我们能做到的冗余 删除。写

要好得多

var mylists = new Dictionary<string,List<int>>();

,让编译器来计算 类型基于赋值 其次,c# 3.0引入了匿名 类型。因为匿名类型由 定义没有名字,你需要到 的类型 变量的初始化

.匿名类型时的表达式

我特别强调。整篇文章c# 3.0仍然是静态类型的,真的!和随后的系列都非常好。

这就是var的作用。其他用途可能就没这么好用了。任何与JScript、VBScript或动态类型的比较都是胡扯。再次注意,var要求,以便使某些其他特性在。net中工作。

对我来说,对var的反感说明了。net中双语的重要性。对于那些使用过VB . net的c#程序员来说,var的优势是显而易见的。标准的c#声明:

List<string> whatever = new List<string>();

在VB .NET中,相当于键入:

Dim whatever As List(Of String) = New List(Of String)

不过,在VB . net中没有人这样做。这样做是愚蠢的,因为从。net的第一个版本开始,你就可以这样做了…

Dim whatever As New List(Of String)

...它创建变量并在一个相当紧凑的行中初始化它。啊,但是如果你想要一个IList<string>,而不是List<string>呢?在VB .NET中,这意味着你必须这样做:

Dim whatever As IList(Of String) = New List(Of String)

就像你在c#中必须做的那样,显然不能使用var:

IList<string> whatever = new List<string>();

如果你需要的类型是不同的,它可以。但优秀编程的基本原则之一是减少冗余,这正是var所做的。

将它用于匿名类型—这就是它存在的目的。其他的都是徒劳无功。像许多使用C长大的人一样,我习惯于查看类型声明的左侧。除非迫不得已,我是不会看右边的。对任何旧的声明使用var使我一直这样做,我个人觉得不舒服。

那些说“没关系,用你喜欢的就行”的人并没有看到全局。每个人都会在某个时候使用其他人的代码,并且必须处理他们在编写代码时所做的任何决定。在不添加“var or not”的情况下,不得不处理完全不同的命名惯例,或者经典的抱怨风格已经够糟糕的了。最糟糕的情况是一个程序员不使用var,然后出现了一个喜欢它的维护者,并使用它扩展代码。所以现在你有一个邪恶的混乱。

标准是一件好事,因为它们意味着你更有可能捡起随机代码,并能够快速地理解它。不同的东西越多,就越难。而移动到“无处不在的var”样式会产生差异。

我不介意动态类型,也不介意隐式类型——在为它们设计的语言中。我很喜欢Python。但是c#被设计为静态显式类型语言,这就是它应该保持的方式。打破匿名类型的规则已经够糟糕的了;让人们更进一步,甚至打破语言的习语,这是我不满意的。既然精灵已经从瓶子里出来了,它就永远不会再进去了。c#将变得四分五裂。不好的。

我认为人们不理解var关键字。 他们把它和Visual Basic / JavaScript关键字搞混了, 这是完全不同的野兽。

很多人认为var关键字意味着 弱类型(或动态类型),而实际上c#是并保持强类型

如果你在javascript中考虑这个:

var something = 5;

你可以:

something = "hello";
在c#的情况下,编译器会从第一个语句推断类型, 导致“int”类型的东西,因此会产生第二条语句

.在异常中 人们只需要明白,使用var关键字并不意味着 动态类型,然后决定var关键字的使用程度, 知道它对于将要编译的内容绝对没有区别 当然var关键字是用来支持匿名类型的, 但是如果你看这个

LedDeviceController controller = new LedDeviceController("172.17.0.1");

这是非常非常冗长的,我相信这是一样可读的,如果不是更多:

var controller = new LedDeviceController("172.17.0.1");

结果是完全相同的,所以是的,我在我的代码中使用它

更新:

也许,只是也许…他们应该用另一个关键词, 那我们就不会有这样的讨论了……也许是“推断”关键字而不是“var”

var对于匿名类型是必不可少的(正如之前对这个问题的回答之一所指出的那样)。

我会把所有其他关于宗教战争利弊的讨论归类为“宗教战争”。我的意思是对……的相对优点进行比较和讨论。

var i = 5;
int j = 5;


SomeType someType = new SomeType();
var someType = new SomeType();

...完全是主观的。

隐式类型意味着对于使用var关键字声明的任何变量都没有运行时惩罚,所以这归结为一个关于如何让开发人员满意的争论。

在CodingHorror上发表关于这个问题的文章偷窃:


不幸的是,你和其他人都错了。虽然我同意你的观点,冗余不是一件好事,但解决这个问题的更好方法应该是这样做:

MyObject m = new();

或者如果你传递参数:

Person p = new("FirstName", "LastName ");

在创建新对象时,编译器从左边推断类型,而不是右边。这比“var”有其他优点,因为它也可以在字段声明中使用(还有其他一些领域,它也可能有用,但我不会在这里讨论)。

最后,这并不是为了减少冗余。不要误解我,“var”在c#中对于匿名类型/投影是非常重要的,但是这里的使用是非常错误的(我已经说了很长很长一段时间了),因为你混淆了正在使用的类型。输入两次太频繁了,但是声明0次就太少了。

Nicholas Paldino . net / c# MVP于2008年6月20日上午08:00


我想如果你主要关心的是必须少打字——那么没有任何争论会动摇你使用它。

如果你只打算作为查看代码的人,那么谁在乎呢?否则,在这种情况下:

var people = Managers.People

没关系,但在这种情况下:

var fc = Factory.Run();

它使我的大脑从代码的“英文”开始形成的任何即时类型推断短路。

否则,就用你最好的判断和编程“礼貌”来对待那些可能不得不为你的项目工作的人。

我尽可能使用var

局部变量不重要的实际类型,如果你的代码写得很好(即,良好的变量名,注释,清晰的结构等)。

我不使用var,因为它违背了c#的根- C/ c++ /Java。尽管这是一个编译器技巧,但它使语言感觉不那么强类型。也许20多年的C语言已经在我们(反变量的人)的头脑中根深蒂固了,我们应该在等号的左右两边都有类型。

话虽如此,我可以看到它对于长泛型集合定义和长类名(如codinghorror.com示例)的优点,但在其他地方,如string/int/bool,我真的看不出这一点。特别是

foreach (var s in stringArray)
{


}

节省3个字符!

对我来说,主要的烦恼是无法看到var代表方法调用的类型,除非你将鼠标悬停在方法上或F12它。

当你将鼠标悬停在“var”上时,VS2008 w/resharper 4.1在工具提示中有正确的输入,所以我认为当你寻找一个类的所有用法时,它应该能够找到这个。

虽然还没有测试它是否这样做。

这次讨论有点晚了,但我想补充一点想法。

对于所有反对类型推断的人(因为这就是我们在这里真正谈论的内容),lambda表达式呢?如果坚持始终显式地声明类型(匿名类型除外),那么如何使用lambdas呢?“不要让我使用鼠标悬停”参数如何适用于var而不是lambdas?

更新

我刚刚想到了一个反对“var”的论点,我认为没有人提到过,那就是它“破坏”了“找到所有引用”,这可能意味着(例如)如果你在重构之前检查类的使用情况,你会错过类通过var使用的所有地方。

取决于,它使代码看起来“更干净”,但同意它使它更难以读…

我想这取决于你的看法。我个人从来没有因为var“误用”而理解一段代码有任何困难,我的同事和我在所有地方都使用它。(我同意智能感知在这方面是一个巨大的帮助。)我欢迎它作为一种消除重复性麻烦的方法。

毕竟,如果语句像

var index = 5; // this is supposed to be bad


var firstEligibleObject = FetchSomething(); // oh no what type is it
// i am going to die if i don't know

如果真的无法处理,没有人会使用动态类型语言。

它可以使代码更简单、更短,特别是对于复杂的泛型类型和委托。

此外,它使变量类型更容易更改。

考虑到智能感知现在是多么强大,我不确定var是否比在一个类中拥有成员变量或在一个方法中定义在可见屏幕区域之外的局部变量更难阅读。

如果你有一行代码,比如

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is比以下更容易或更难读:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

当你不想重复自己的时候,var是很棒的。例如,我昨天需要一个类似于此的数据结构。您喜欢哪种表示法?

Dictionary<string, Dictionary<string, List<MyNewType>>> collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

var collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

注意,在本例中使用var引入了很少的歧义。然而,有时候这并不是一个好主意。例如,如果我像下面这样使用var

var value= 5;

当我可以只写真正的类型并消除5应该如何表示的任何歧义时。

double value = 5;

它当然可以让事情变得更简单,从我昨天写的代码来看:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

如果没有var,这将是非常冗长的。

附录:花一点时间学习带有真正的类型推断的语言(例如f#),就会发现编译器在正确获取表达式类型方面是多么出色。这当然意味着我倾向于尽可能多地使用var,现在使用显式类型表明变量不是初始化表达式的类型。

在测试过程中,我发现自己的代码是这样的:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

现在,有时,我想看看SomeOtherThing本身包含什么,SomeOtherThing不是CallMethod()返回的相同类型。因为我使用了var,我只是改变了这个:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

:

var something = myObject.SomeProperty.SomeOtherThing;

如果没有var,我也必须不断改变左边声明的类型。我知道这是小事,但它非常方便。

我不认为var per say是一个可怕的语言特性,因为我每天都在Jeff Yates描述的代码中使用它。实际上,我几乎每次使用var都是因为泛型会导致一些极其冗长的代码。我活在冗长的代码中,但是泛型太过分了。

也就是说,我(显然……)认为var被滥用的时机已经成熟。如果在一个方法中,代码超过20行,并且到处都是vars,那么维护很快就会变成一场噩梦。此外,在教程中使用var是违背直觉的,在我的书中是一个大禁忌。

另一方面,var是一个“简单”的特性,新程序员会抓住并喜欢它。然后,在几分钟/几小时/几天内,当他们开始触及极限时,遇到了巨大的障碍。为什么我不能从函数中返回var这类问题。此外,向强类型语言添加伪动态类型很容易让新开发人员感到困惑。从长远来看,我认为var关键字实际上会让新程序员更难学习c#。

也就是说,作为一个有经验的程序员,我确实使用var,主要是在处理泛型(显然是匿名类型)时。我相信var将会是c#中最被滥用的特性之一。

在边缘情况下肯定会有分歧,但我可以告诉你我的个人指导方针。

当我决定使用var时,我查看这些标准:

  • 变量的类型是上下文中的明显的 [to a human]
  • 变量的确切类型是不是特别相关 [to a human]
    [例如,你可以弄清楚算法在做什么,而不用关心你使用的是哪种容器]
  • 类型名非常长,会影响代码的可读性(提示:通常是通用的)

相反,这些情况会促使我不使用var:

  • 类型名称相对较短且易于阅读(提示:通常不是通用的)
  • 类型是不明显,来自初始化式的名称
  • 确切的类型对于理解代码/算法非常重要
  • 在类层次结构上,当一个人不能很容易地知道正在使用层次结构的哪个级别时

最后,我绝不会将var用于本机值类型或相应的nullable<>类型(intdecimalstringdecimal?,…)。这里有一个隐含的假设,如果你使用var,一定有“一个原因”。

这些都是指导方针。你还应该考虑你同事的经验和技能,算法的复杂性,变量的寿命/范围,等等。

大多数时候,没有完美的正确答案。或者,这并不重要。

[编辑:删除重复的子弹]

必要的LINQ:

除非绝对必要,否则最好不要显式声明范围变量的类型。例如,下面的代码编译干净,但是编译器可以在没有正式声明的情况下推断出类型:

List<string> list = new List<string> { "LINQ", "query", "adventure" };
var query = from string word in list
where word.Contains("r")
orderby word ascending
select word;

显式声明range变量的类型会强制对LINQ Cast操作符进行幕后调用。此调用可能会产生意想不到的结果,并可能会损害性能。如果您在LINQ查询中遇到性能问题,像这里所示的强制转换可能是开始寻找罪魁祸首的一个地方。(此规则的一个例外是当您使用非泛型Enumerable时,在这种情况下您应该使用强制转换。)

没有,只是不需要写两次类型名。http://msdn.microsoft.com/en-us/library/bb383973.aspx

这纯粹是为了方便。编译器将推断类型(基于右边表达式的类型)。

在大多数情况下,只是输入它更简单——想象一下

var sb = new StringBuilder();

而不是:

StringBuilder sb = new StringBuilder();

有时它是必需的,例如:匿名类型,比如。

var stuff = new { Name = "Me", Age = 20 };

我个人喜欢使用它,尽管它会降低代码的可读性和可维护性。

你不需要写出类型名,这不会降低性能,因为类型是在编译时解析的。

你最可能需要它的时候是匿名类型(100%需要);但它也避免了琐碎案件的重复,IMO使界限更加清晰。对于简单的初始化,我不需要看到类型两次。

例如:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(请不要编辑上面的hscroll -它有点证明了这一点!!)

与:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

然而,在某些情况下,这是一种误导,并可能导致错误。如果原始变量和初始化类型不相同,使用var时要小心。例如:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}


// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

使用var而不是显式类型使重构更容易(因此我必须反驳之前的帖子,他们的意思是它没有区别,或者它纯粹是“语法糖”)。

您可以更改方法的返回类型,而无需更改调用此方法的每个文件。想象一下

...
List<MyClass> SomeMethod() { ... }
...

就像这样

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
System.Console.WriteLine(c.ToString());
...

如果你想重构SomeMethod()以返回IEnumerable<MySecondClass>,你必须在你使用该方法的每个地方改变变量声明(也是在foreach中)。

如果你写

...
var list = obj.SomeMethod();
foreach (var element in list)
System.Console.WriteLine(element.ToString());
...

相反,你不需要改变它。

您可以让编译器(以及接下来维护代码的人员)从初始化式赋值的右边推断类型。如果这种推断是可能的,编译器可以这样做,从而节省了您的一些输入。

如果这个推断对那个可怜的家伙来说很容易,那么你没有伤害到任何东西。如果推断很难,那么作为一般规则,您已经使代码更难维护

最后,如果您希望该类型是某个特定的类型,而您的初始化表达式实际上具有不同的类型,那么使用var意味着您将更难找到引起的错误。通过显式地告诉编译器你想要的类型是什么,当类型不是,你会得到一个即时诊断。在类型声明和使用“var”时,你不会在初始化时得到错误;相反,在某些使用var表达式分配的标识符的表达式中,您会得到一个类型错误,而且很难理解其中的原因。

寓意是,要谨慎使用var;您通常不会给您自己或您的下游维护人员带来很多好处。并希望他以同样的方式推理,这样你就不会因为认为使用var很容易而猜测他的意图。在编写一个具有较长生命周期的系统时,优化输入量是一个错误。

有时编译器也能比开发人员“更好”地推断出需要什么——至少开发人员不了解他所使用的api需要什么。

例如-当使用linq时:

示例1

Func<Person, bool> predicate = (i) => i.Id < 10;
IEnumerable<Person> result = table.Where(predicate);

示例2

var predicate = (Person i) => i.Id < 10;
var result = table.Where(predicate);
在上面的代码中-假设一个是使用Linq到Nhibernate或Linq到SQL,示例1将 返回Person对象的整个结果集,然后在客户端进行筛选。 然而,示例2将在服务器上执行查询(例如在Sql server上使用Sql),因为编译器足够聪明,可以计算出Where函数应该采用表达式>而不是Func。< / p >

示例1中的结果在返回IEnumerable时也不能在服务器上进一步查询,而在示例2中,编译器可以计算出结果是否应该是IQueryable而不是IEnumerable

我曾经认为var关键字是一个伟大的发明,但我把一个限制,这是

  • 只在类型很明显的情况下使用var(不要滚动或查看返回类型)

我意识到这并没有给我带来任何好处,并从我的代码中删除了所有的var关键字(除非他们是特别需要的),现在我认为他们使代码可读性更差,特别是对其他人阅读你的代码。

它隐藏了意图,并且在至少一个实例中,由于类型的假设而导致某些代码的运行时错误。

从关于这一主题的讨论来看,结果似乎是:

好:var customers = new List<Customer>();

争议:var customers = dataAccess.GetCustomers();

忽略“var”神奇地帮助重构的错误观点,对我来说最大的问题是人们坚持认为他们不关心返回类型是什么,“只要他们能枚举集合”。

考虑:

IList<Customer> customers = dataAccess.GetCustomers();


var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

现在考虑:

var customers = dataAccess.GetCustomers();


var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

现在,去重构数据访问类,让GetCustomers返回IEnumerable<Customer>,看看会发生什么…

这里的问题是,在第一个示例中,您明确了对GetCustomers方法的期望—您说您希望它返回一些行为类似于列表的东西。在第二个示例中,这个期望是隐式的,从代码中不能立即看出。

(对我来说)有趣的是,许多支持var的论点说“我不在乎它返回什么类型”,但接着说“我只需要迭代它……”。(因此它需要实现IEnumerable接口,这意味着类型问题)。

对于那些认为var节省时间的爱好者来说,输入它需要更少的按键:

StringBuilder sb = new StringBuilder();

var sb = new StringBuilder();

如果你不相信,你可以数数……

19对21

如果有必要我会解释的,但你试试吧……(取决于你的智能感知的当前状态,你可能需要为每一个输入更多)

你能想到的每一种类型都是如此!!

我个人的感觉是,除非在不知道类型的情况下,否则永远不应该使用var,因为它降低了代码中的识别可读性。大脑识别字体的时间比识别一整行字体要长。那些懂机器码和比特的老家伙知道我在说什么。大脑是并行处理的,当你使用var时,你强迫它序列化它的输入。为什么会有人想让自己的大脑更努力地工作呢?这就是电脑的作用。

令人惊讶的是,到目前为止还没有注意到这一点,但对foreach循环变量使用var是常识。

如果您指定了特定的类型,则可能会有编译器无声地将运行时强制转换插入程序的风险!

foreach (Derived d in listOfBase)
{

上面的代码将被编译。但是编译器会插入一个从BaseDerived的向下转换。因此,如果列表中的任何内容在运行时不是Derived,则存在无效的强制转换异常。类型安全受到损害。隐形演员太可怕了。

排除这种情况的唯一方法是使用var,这样编译器就可以根据列表的静态类型来确定循环变量的类型。

Var一点也不像变量。变量仍然是强类型的,只是你不需要按下键来得到它。您可以在Visual Studio中将鼠标悬停在它上以查看类型。如果您正在阅读打印的代码,则可能需要稍微考虑一下以确定类型是什么。但是只有一行声明了它,而有很多行使用它,所以给东西起个像样的名字仍然是让你的代码更容易理解的最好方法。

使用智能感知是懒惰吗?这比输入整个名字还少。或者有些事情不那么费力,但不值得批评?我认为有,var就是其中之一。

因冗余原因删除。

vars仍然初始化为正确的变量类型-编译器只是从上下文推断它。正如您所提到的,var使我们能够存储对匿名类实例的引用——但它也使更改代码变得更容易。例如:

// If you change ItemLibrary to use int, you need to update this call
byte totalItemCount = ItemLibrary.GetItemCount();


// If GetItemCount changes, I don't have to update this statement.
var totalItemCount = ItemLibrary.GetItemCount();

是的,如果很难从变量的名称和用法中确定变量的类型,那么无论如何都要显式声明它的类型。

这并不坏,这更多的是一种风格上的东西,往往是主观的。当你使用var或不使用var时,它会增加不一致性。

另一种值得关注的情况是,在下面的调用中,你不能仅通过查看代码来判断CallMe返回的类型:

var variable = CallMe();

这是我对var的主要抱怨。

当我在方法中声明匿名委托时,我使用var,在某种程度上var看起来比使用Func更干净。考虑下面的代码:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
...
});

编辑:根据Julian的输入更新了最后一个代码示例

这两种说法都不是绝对正确的;var对可读性有积极和消极的影响。在我看来,当下列任意一个为真时,应该使用var:

  1. 类型是匿名的(好吧,在这里你没有任何选择,因为在这种情况下必须是var)
  2. 根据指定的表达式(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating()),类型是明显的。

var没有性能影响,因为它是语法糖;一旦编译成IL,编译器就会推断出类型并定义它;没有任何实际上动态内容。

在我看来,大量使用var没有问题。它本身不是一个类型(您仍然在使用静态类型)。相反,这只是一个节省时间的方法,让编译器自己判断要做什么。

像任何其他节省时间的方法(例如自动属性)一样,在到处使用它之前,最好先了解它是什么以及它是如何工作的。

我认为你误解了c#中var的用法。它仍然是强类型,不像VB的变体类型,所以无论是否使用它都不会对性能造成影响。

因为它对最终编译的代码没有影响,所以它实际上是一个设计器的选择。就我个人而言,我不使用它,因为我发现定义了完整类型的代码更容易阅读,但我可以想象,几年后,完整类型声明将像现在的匈牙利符号一样被看待——额外的类型与默认情况下智能感知提供给我们的信息相比并没有真正的好处。

在我看来,Var在c#中是好事tm。任何这样类型的变量仍然是强类型的,但是它从赋值函数的右边得到它的类型。因为类型信息在右侧可用,在大多数情况下,也必须在左侧输入它是不必要的和过于冗长的。我认为这在不降低类型安全性的情况下显著提高了可读性。

在我看来,从可读性的角度来看,为变量和方法使用良好的命名约定比显式类型信息更重要。如果我需要类型信息,我总是可以将鼠标悬停在变量上(在VS中)并获得它。但是,一般来说,显式类型信息对于读者来说是不必要的。对于开发人员来说,在VS中,不管变量是如何声明的,你仍然会得到智能感知。说了这么多,仍然可能在某些情况下显式声明类型是有意义的——也许你有一个返回List<T>的方法,但你想在你的方法中把它当作IEnumerable<T>。为了确保您正在使用接口,声明接口类型的变量可以使其显式化。或者,您可能希望声明一个没有初始值的变量——因为它立即根据某些条件获得一个值。在这种情况下,您需要类型。如果类型信息是有用的或必要的,那么就使用它。不过,我觉得通常没有必要,在大多数情况下,没有它代码更容易阅读。

var还不错。记住这一点。var还不错。重复一遍。var还不错。记住这一点。var还不错。重复一遍。

如果编译器足够聪明,可以从上下文中找出类型,那么您也可以。你不需要在申报时把它写下来。而智能感知让这变得更加不必要。

var还不错。记住这一点。var还不错。重复一遍。var还不错。记住这一点。var还不错。重复一遍。

如果有人使用var关键字是因为他们不想“找出类型”,那肯定是错误的原因。var关键字不会创建具有动态类型的变量,编译器仍然必须知道该类型。由于变量总是具有特定的类型,因此如果可能的话,该类型在代码中也应该是明显的。

使用var关键字的理由如下:

  • 在需要的地方,即声明匿名类型的引用。
  • 它使代码更具可读性,即删除重复的声明。

写出数据类型通常会使代码更容易理解。它显示了您正在使用的数据类型,因此您不必通过先弄清楚代码的功能来弄清楚数据类型。

第一。

var不是一个类型,也不是一些特殊的特性(如c# 4.0 dynamic)。它只是一个语法糖。你要求编译器通过右边的表达式来推断类型。唯一需要的地方是匿名类型。

我不认为使用var既好又坏,这是一种编码风格。我个人不使用它,但我不介意其他团队成员使用它。

我想你在你的问题中指出了var的主要问题:“我不需要弄清楚类型”。正如其他人指出的那样,var是有一席之地的,但如果你不知道你正在处理的类型,你很有可能会遇到问题——不是在所有情况下,但那里有足够的气味,所以你应该怀疑。

好吧,这个问题在整个过程中几乎都是固执己见的,但是我会试着给出我的观点——尽管我认为我的观点是如此混乱,以至于你可能无论如何都不会从中得到什么。

首先-有匿名类型,你需要使用“ var”关键字来分配一个具有匿名类型的对象作为它的类-这里没有太多的讨论,“ var”是必要的。

然而,对于更简单的类型,int、 longs、 string 等等,我倾向于使用适当的类型。主要是因为它有点像“懒人的工具”,我在这里没有看到太多的收获,很少的击键和可能的混淆,它可能提供以后的道路只是不值得这样做。特别是浮点数的各种类型(浮点数、双精度数、十进制数)让我感到困惑,因为我对文字中的后缀不是很了解——我喜欢在源代码中看到这种类型。

因此,如果类型更复杂并且/或者它在赋值的右边显式地重复,我倾向于使用 var lot。这可能是一个 List<string>或等,如:

var list = new List<string>();

在这种情况下,我认为重复两次类型是没有用的——特别是当您开始更改代码和类型时——泛型类型可能会变得越来越复杂,因此必须更改两次只是一种痛苦。当然,如果您希望根据 IList<string>编写代码,那么您必须显式地命名该类型。

简而言之,我要做的是:

  • 当类型较短或不能脱离上下文读取时,显式命名该类型
  • 当必须使用 var 时使用它(duh)
  • 当 var (在我看来)不影响可读性时,可以使用 var

当然,int很简单,但是当变量的类型是 IEnumerable<MyStupidLongNamedGenericClass<int, string>>时,var 会使事情变得更简单。

我只在清楚地看到使用了什么类型时才使用 var。

例如,在本例中我将使用 var,因为您可以立即看到 x 将属于“ MyClass”类型:

var x = new MyClass();

在这种情况下,我不会使用 var,因为你必须在代码上拖动鼠标,然后查看工具提示,看看 MyFunction 返回什么类型:

var x = MyClass.MyFunction();

特别是,在右边甚至不是一个方法,而只是一个值的情况下,我 永远不会使用 var:

var x = 5;

(因为编译器不能知道我是否需要一个字节、 short、 int 或者其他什么)

除了可读性问题,使用“ var”还有一个真正的问题。当用于定义代码中稍后分配的变量时,如果用于初始化变量的表达式的类型更改为较窄的类型,则可能导致代码中断。通常情况下,重构一个方法以返回比以前更窄的类型是安全的: 例如,用某个类‘ Foo’替换‘ Object’的返回类型。但是如果有一个变量的类型是基于方法推断出来的,那么改变返回类型将意味着这个变量可以被赋予一个非 Foo 对象:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

因此在本例中,更改 getFoo 的返回类型将使 getNonFoo 的赋值非法。

如果 getFoo 和它的所有用途都在同一个项目中,这并不是什么大问题,但是如果 getFoo 在一个外部项目使用的库中,你就不能再确定如果用户像这样使用“ var”,缩小返回类型不会破坏一些用户的代码。

正是出于这个原因,当我们在 Curl 编程语言中添加一个类似的类型推断特性(在 Curl 中称为‘ def’)时,我们阻止了对使用这种语法定义的变量的赋值。

Eric 的回答是..。

C # 中泛型类型的命名空间作用域别名

是相关的。

问题的一部分在于 C # 中没有强类型别名。因此许多开发人员使用 Var作为部分代理。

别用那个,会让你的代码不可读。

总是使用尽可能严格的打字,拐杖只会让你的生活变成地狱。

这并没有错,但也可能是不恰当的。

Var x = 5; (坏)

Var x = new SuperDooperClass () ; (好)

Var x = from t in db。选择 new { Property1 = t.Field12} ; (更好)

“关于我的品味,你唯一能说的就是它过时了,假以时日,你的品味也会跟着过时。”托尔金。

var 是 C # 3.0和 LINQ 中为 anonymous types引入的占位符。

因此,它允许为较少数量的列编写 LINQ 查询,比方说,在一个集合中。不需要在内存中复制信息,只加载完成需要完成的任务所必需的内容。

var的使用一点也不差,因为它实际上不是一个类型,而是像其他地方提到的那样,一个类型的占位符,这个类型必须在等式的右边定义。然后,编译器将用类型本身替换关键字。

即使使用 IntelliSense,当类型的名称需要长时间键入时,它也特别有用。只需编写 var并实例化它。其他程序员会在之后阅读你的代码,他们会很容易理解你在做什么。

就像吸毒一样

public object SomeObject { get; set; }

而不是:

public object SomeObject {
get {
return _someObject;
}
set {
_someObject = value;
}
}
private object _someObject;

每个人都知道这个属性在做什么,因为每个人都知道 var关键字在做什么,而且任何一个示例都可以通过使其更轻巧来简化可读性,并使程序员更容易编写有效的代码。

var很好,因为它遵循经典的 干的规则,当您在声明变量的同一行中指示类型时,它尤其优雅。(例如 var city = new City())

如果您知道类型,请使用该类型。 如果你不知道这种类型,为什么不呢? 如果你不知道这种类型,没关系——你已经找到了唯一有效的用途。

我很抱歉,但是如果你能做的最好的事情就是“让所有代码排成一行”,这不是一个好的答案。找到格式化代码的不同方法。

为什么 var 不应该仅仅用作“输入快捷方式”,而应该用于主要为其设计的场景,有一个很好的论点: Resharper (至少 v4.5)如果将类型表示为 var,则无法找到该类型的用法。在重构或分析源代码时,这可能是一个真正的问题。

如果你懒惰并且除了匿名类型之外还使用 var,那么在命名这些变量时应该要求你使用匈牙利命名法。

var iCounter = 0;

生命!

天啊,我真想念 VB。

大多数人忽视的是:

var something = new StringBuilder();

打字速度通常没有

StringBuilder something = KEY'TAB'();

对于 LINQ,使用 var的另一个很好的理由是编译器可以更好地优化查询。

如果你使用一个静态列表来存储结果,它会在你把它分配给列表的地方执行,但是使用 var,它可能会将原始查询与代码中的后续查询合并,从而对数据库进行更优化的查询。

我有一个例子,我在第一个查询中提取了一些数据,然后进行循环,并请求更多的数据来打印一个表。

LINQ 将这些合并,以便第一个只提取 id。

然后在循环中,它添加了一个额外的连接,这个连接是我没有做过的,用来获取我包含在原始文件中的数据。

经过测试,这种方法被证明效率更高。

如果我们没有使用 var,它会完全按照我们编写的方式进行查询。

作为一名十年的 Java 专业人士,我对 C # 世界相当陌生。我最初的想法是“哦,不!字体安全就这样泡汤了”。然而,我对 var 了解得越多,就越喜欢它。

Var 与显式声明的类型一样,都是类型安全的。这都是关于编译时语法 Sugar 的。

2)它遵循 DRY 的原则(不要重复自己)。DRY 完全是为了避免冗余,并且在两边都命名类型肯定是多余的。避免冗余完全是为了使代码更容易更改。

3)知道确切的类型。.好吧。.我认为你总是有一个大概的想法,你有一个整数,一个套接字,一些 UI 控件,或其他什么。智慧感应会从这里指引你。知道确切的类型通常并不重要。例如,我认为99% 的情况下,你并不关心给定的变量是 long 变量还是 int 变量、 float 变量还是 double 变量。对于最后1% 的情况,只要将鼠标指针悬停在 var 关键字上方就可以了。

4)我见过一个荒谬的论点,认为现在我们需要回到1980年的匈牙利疣,以便区分可变类型。毕竟,在蒂莫西 · 道尔顿(Timothy Dalton)扮演詹姆斯 · 邦德(James Bond)的时代,这是唯一能够分辨变量类型的方法。但现在是2010年。我们已经学会了根据变量的用法和内容来命名变量,并让 IDE 指导我们确定它们的类型。继续这样 Var 就不会伤害你。

总而言之,var 不是什么大不了的东西,但是它确实是一个很好的东西,Java 最好尽快复制它。所有反对的论点似乎都基于 IDE 之前的谬误。我会毫不犹豫地使用它,我很高兴 R # 帮助我这样做。

Var 是处理匿名类型的方法,无论是否来自 LINQ 语句。任何其他用途都在很大程度上取决于谁将阅读您的代码以及适当的指导方针。

如果您是唯一的听众,或者您的听众喜欢使用 var,或者非常熟悉您的代码,那么我想这并不重要。如果你像这样使用它: Var s = new SqlConnection (),那么它在很大程度上没有关系,可能会提高代码的可读性。如果人们不太挑剔,他们可以做一些工作来了解类型,当它不明显时(这在大多数情况下是不需要的,如何使用它在下面的陈述中通常会解释一切) ,然后就可以了。

但是,如果你有挑剔、思想封闭的队友,他们喜欢抱怨,或者如果你的公司的设计指南明确禁止在类型不明显的情况下使用 var,那么你很可能会遇到强烈的反对意见。

如果使用 var 使您的代码难以阅读,那么您可能会因使用 var 而遭受损失,即使这可能是您的应用程序设计造成的。

如果 var 引入了歧义(有点像 IEnumable/IEnumable 示例) ,那么就不要使用它,而要显式地使用它。但是 var 确实有它的便利性,在某些情况下,恕我直言,甚至通过减少杂乱来提高可读性。

Var 就像儿童书中的虚线,孩子们必须填满它。除了在这种情况下,编译器将使用通常写在 = 符号后面的正确类型填充它。

可以给局部变量一个推断的 var“类型”,而不是一个显式的类型。Var 关键字指示编译器从初始化语句右侧的表达式推断变量的类型。

//z 被编译为一个 int

var z = 100;

//s 被编译为下面的字符串

var s = "Hello";

//a 被编译为 int []

var a = new[] { 0, 1, 2 };

//expr 被编译为 IEnumable 或者可能是 IQueryable

var expr =
from c in customers
where c.City == "London"
select c;

//anon 被编译为匿名类型

var anon = new { Name = "Terry", Age = 34 };

//List 被编译为 List

var list = new List<int>();


var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

Var 不能用于类范围内的字段。

使用 var 声明的变量不能在初始化表达式中使用。换句话说,这个表达式是合法的: int i = (i = 20) ; 但是这个表达式会产生编译时错误: var i = (i = 20) ;

不能在同一语句中初始化多个隐式类型的变量。

如果名为 var 的类型在作用域中,那么 var 关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。