在C#中使用var关键字

时间:2008-09-03 11:29:58

标签: c# type-inference 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(someList中的var项目){// ...}等效更好。

这里存在关于类型安全的真正担忧 - 例如,如果我们将该查询的结果放入接受IEnumerable&lt; int&gt;的重载方法中。和IEnumerable&lt; double&gt;调用者可能会无意中传入错误的类型。

var 确实保持强类型,但问题是这个类型在定义上不是立即明显是危险的,当重载意味着编译器错误可能不是当你无意中将错误的类型传递给方法时发出。

86 个答案:

答案 0 :(得分:293)

我仍然认为var可以使代码在某些情况下更具可读性。如果我有一个带有Orders属性的Customer类,并且我想将其分配给变量,我将执行此操作:

var orders = cust.Orders;

我不在乎Customer.Orders是IEnumerable<Order>ObservableCollection<Order>还是BindingList<Order> - 我想要的只是将该列表保留在内存中以迭代它或得到它的计数或者以后的东西。

将上述声明与:

对比
ObservableCollection<Order> orders = cust.Orders;

对我来说,类型名称只是噪音。如果我回去决定改变Customer.Orders的类型(从ObservableCollection<Order>IList<Order>),那么我也需要更改声明 - 我不需要如果我在第一时间使用var就行了。

答案 1 :(得分:168)

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

不可否认,这可能意味着我们正在处理的类型尚不清楚。所以呢?这实际上是解耦设计的重点。在处理接口时,您强调对变量类型感兴趣。 var更进一步,真实,但我认为从可读性的角度来看,论证仍然是相同的:程序员实际上不应该对变量的类型感兴趣,而是对变量确实。这就是为什么微软也称类型推断为“鸭子打字”。

那么,当我使用var声明变量时,变量会做什么?很容易,它可以做任何IntelliSense告诉我的事情。关于忽略IDE的C#的任何推理都不符合现实。实际上,每个C#代码都在支持IntelliSense的IDE中编程。

如果我使用的是var声明的变量,并且对变量的含义感到困惑,那么我的代码就会出现根本性的错误。 var不是原因,它只会使症状可见。不要怪信使。

现在,C#团队已经发布了一个编码指南,指出var用于捕获创建匿名类型的LINQ语句的结果(因为在这里,我们有没有var的真正替代品。好吧,搞砸了。只要C#团队没有给我这个指南的合理论据,我就会忽略它,因为在我的专业和个人看来,它是纯粹的胡扯。 (对不起;我没有相关指南的链接。)

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

答案 2 :(得分:118)

Var,在我看来,在C#中是好东西 tm 。所有类型的变量仍然是强类型的,但它从定义它的赋值的右侧获得它的类型。因为类型信息在右侧可用,所以在大多数情况下,还必须在左侧输入它,这是不必要的并且过于冗长。我认为这可以在不降低类型安全性的情况下显着提高可读性。

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

答案 3 :(得分:91)

这些都不是绝对正确的; var可对可读性产生正面和负面影响。在我看来,如果满足以下任一条件,则应使用var

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

    var没有性能影响,因为它是语法糖;编译器推断出类型,并在编译成IL后定义它;没有什么实际动态的。

答案 4 :(得分:68)

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

为什么引入了var关键字?

  

有两个原因,一个是原因   今天存在,一个会突然出现的   在3.0。

     

第一个原因是这段代码是   令人难以置信的丑陋因为所有的   冗余:

     

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

     

这是一个简单的例子 - 我已经   写得更糟。任何时候你被迫   两次输入完全相同的东西,   这是我们可以做到的冗余   去掉。写得好多了

     

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

     

让编译器搞清楚什么   类型基于作业。

     

其次,C#3.0引入了匿名   类型。由于匿名类型由   定义没有名称,你需要来   能够推断出的类型   初始化的变量   表达式,如果它的类型是匿名的。

强调我的。整篇文章C# 3.0 is still statically typed, honest!和随后的series非常好。

这是var的用途。其他用途可能不会那么好用。与JScript,VBScript或动态类型的任何比较都是总上铺。请再次注意,var 必需,以便在.NET中使用某些其他功能。

答案 5 :(得分:53)

我认为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。

答案 6 :(得分:40)

我们采用了“为人而不是机器编写代码”的理念,假设您在维护模式下花费的时间比在新开发上多花费多倍。

对我来说,这排除了编译器“知道”变量的类型的论点 - 当然,你不能在第一次编写无效代码,因为编译器会停止编译代码,但是当下一个开发人员是在6个月内阅读代码时,他们需要能够正确或错误地推断出变量的作用,并快速找出问题的原因。

因此,

var something = SomeMethod();

我们的编码标准是非法的,但我们的团队鼓励以下内容,因为它提高了可读性:

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

答案 7 :(得分:39)

这不错,它更像是一种风格化的东西,往往是主观的。当你使用var时,它可以添加不一致性。

另一个值得关注的案例,在下面的调用中,您只能通过查看CallMe返回的类型代码来判断:

var variable = CallMe();

这是我对var。

的主要抱怨

当我在方法中声明匿名委托时,我使用var,不知何故var看起来比我使用Func更清晰。请考虑以下代码:

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

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

答案 8 :(得分:36)

Var根本不是变体。该变量仍然是强类型的,只是你没有按键来获得它。您可以将鼠标悬停在Visual Studio中以查看其类型。如果您正在阅读打印的代码,那么您可能需要考虑一下才能弄清楚类型是什么。但是只有一行声明它并且许多行使用它,所以给出正确的名称仍然是使代码更容易理解的最佳方法。

使用Intellisense懒惰吗?打字比整个名字少。或者有些东西工作少但不值得批评?我认为有,而var就是其中之一。

答案 9 :(得分:27)

您最需要的时间是匿名类型(需要100%);但它也避免了重复的微不足道的情况,IMO使线条更清晰。对于简单的初始化,我不需要看两次类型。

例如:

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

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

VS

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);

答案 10 :(得分:17)

一个特殊情况,其中var很难:脱机代码审查,尤其是在纸上完成的。

你不能依赖鼠标悬停。

答案 11 :(得分:17)

我看不出有什么大不了的......

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

你仍然对'某事'有完整的智能感知,对于任何模棱两可的情况,你有单位测试,对吧? (你呢?)

它不是varchar,它不是暗淡的,它肯定不是动态或弱打字。它正在停止像这样的maddnes:

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

并将整个思维结构减少到:

var v = new List<somethinglongtypename>();

很好,不太好:

v = List<somethinglongtypename>();

但那就是Boo的用途。

答案 12 :(得分:17)

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

使用var关键字的充分理由是:

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

写出数据类型通常会使代码更容易理解。它显示了您正在使用的数据类型,因此您不必通过首先确定代码的作用来确定数据类型。

答案 13 :(得分:11)

鉴于Intellisense现在有多强大,我不确定var是否比在类中具有成员变量或在可见屏幕区域定义的方法中的局部变量更难读。

如果您有一行代码,例如

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

比阅读更容易或更难:

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

答案 14 :(得分:10)

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

答案 15 :(得分:10)

我认为VAR的关键是只在适当的时候使用它,即在Linq中做事情时(也可能在其他情况下)。

如果你已经得到某种类型的东西那么你应该使用它 - 不这样做是简单的懒惰(而不是通常被鼓励的创造性懒惰 - 优秀的程序员经常努力工作非常困难,可以首先考虑事物的来源。)

全面禁止与首先滥用构造一样糟糕,但确实需要有合理的编码标准。

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

我怀疑这一个将要运行并运行( - :

墨菲

答案 16 :(得分:9)

post on this issue at CodingHorror

中被盗

不幸的是,你和其他所有人都错了。虽然我同意你的看法,冗余并不是一件好事,但解决这个问题的更好方法就是做以下事情:

MyObject m = new();

或者如果您要传递参数:

Person p = new(“FirstName”,“LastName”;

在创建新对象的地方,编译器从左侧推断出类型,而不是从右侧推断出类型。这比“var”还有其他优点,因为它也可以用在字段声明中(还有一些其他区域也可以用,但我不会在这里介绍它。)

最后,它并不是为了减少冗余。不要误解我的意思,“var”对于匿名类型/投影来说在C#中非常重要,但是这里的使用只是为了解决(我已经说了这么长时间),因为你混淆了正在使用。必须经常输入两次,但是将其声明为零是太少了。

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


我想如果你主要担心的是必须输入更少 - 那么就没有任何争论会影响你使用它。

如果您只是曾经成为查看您的代码的人,那么谁在乎呢?否则,在这种情况下:

var people = Managers.People

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

var fc = Factory.Run();

它可以缩短我的大脑可以从代码的“英语”开始形成的任何即时类型推论。

否则,只需使用您的最佳判断并对可能需要为您的项目工作的其他人进行“礼貌”编程。

答案 17 :(得分:9)

使用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());
...

相反,您不必更改它。

答案 18 :(得分:8)

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

基本上我不想用鼠标打猎。它可能无法使用。

答案 19 :(得分:8)

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

C#的var非常酷,因为看起来像一样动态打字,但实际上是静态打字 - 编译器强制执行正确的用法。

你的变量的类型并不那么重要(之前已经说过了)。从上下文(它与其他变量和方法的交互)及其名称应该相对清楚 - 不要指望 customerList 包含int ......

我还在等着看我的老板对这件事的看法 - 我有一个“继续”使用3.5中的任何新结构,但我们将如何处理维护?

答案 20 :(得分:7)

当只清楚看到使用的是什么类型时,我只使用var。

例如,在这种情况下我会使用var,因为您可以立即看到x将是“MyClass”类型:

var x = new MyClass();

我不会在这种情况下使用var,因为你必须将鼠标拖到代码上并查看工具提示以查看MyFunction返回的类型:

var x = MyClass.MyFunction();

特别是,我从不在右侧甚至不是方法但只有一个值的情况下使用var:

var x = 5;

(因为编译器无法知道我是否需要byte,short,int或其他)

答案 21 :(得分:7)

我想这取决于你的观点。由于var“滥用”,我个人从未理解过一段代码,而且我的同事和我一直在使用它。 (我同意Intellisense在这方面是一个巨大的帮助。)我欢迎它作为一种消除重复性的方法。

毕竟,如果声明如

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

实际上是不可能处理的,没有人会使用动态类型语言。

答案 22 :(得分:7)

IEnumerable<int>IEnumerable<double>之间进行比较时,您无需担心 - 如果传递错误的类型,则无论如何都不会编译代码。

不关心类型安全性,因为var 是动态的。它只是编译器魔术,你所做的任何类型的不安全的调用都会被捕获。

Linq绝对需要

Var

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
    };

现在看一下intellisense中的 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;

答案 23 :(得分:6)

在测试期间,我发现自己有这样的代码:

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,我也必须继续改变左侧的声明类型。我知道这很小,但非常方便。

答案 24 :(得分:6)

对我而言,对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所做的。

答案 25 :(得分:6)

将它用于匿名类型 - 这就是它的用途。其他任何东西都用得太过分了。像很多在C上长大的人一样,我习惯于查看声明类型的左边。除非必须,否则我不会看右边。使用var进行任何旧声明都会让我一直这样做,我个人觉得这很不舒服。

那些说“没关系,用你满意的东西”的人并没有看到全貌。每个人都会在某个时刻接受其他人的代码,并且必须处理他们在编写代码时做出的任何决定。不得不处理截然不同的命名约定,或者 - 经典的抱抱支撑样式,而不是将整个'var或不添加'混合在一起。最糟糕的情况是一个程序员没有使用var,然后是一个喜欢它的维护者,并使用它扩展代码。所以现在你有一个邪恶的混乱。

标准是一件好事,正是因为它们意味着您更有可能获得随机代码并能够快速完成它。不同的东西越多,越难。转向'var everywhere'风格会产生差异。

我不介意动态打字,我不介意打字输入 - 用于为他们设计的语言。我非常喜欢Python。但是C#被设计为一种静态明确类型的语言,它应该如何保留。打破匿名类型的规则已经够糟糕了;让人们更进一步,进一步打破语言的习语,这是我不满意的事情。既然精灵已经不在瓶子里了,它就永远不会再回来了.C#将会变成阵营。不好。

答案 26 :(得分:6)

对于认为var节省时间的afficionados,键入的键击次数较少:

StringBuilder sb = new StringBuilder();

大于

var sb = new StringBuilder();

如果你不相信我,请记下他们......

19对21

我会解释是否必须,但只是尝试一下......(根据你的智能感知的当前状态,你可能需要为每一个输入更多的东西)

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

我个人的感觉是永远不应该使用var,除非类型未知,因为它会降低代码中的识别可读性。识别类型比整行更需要大脑。了解机器代码和位的老定时器确切地知道我在说什么。大脑并行处理,当你使用var时,你强制它序列化它的输入。为什么有人想让他们的大脑更努力?这就是计算机的用途。

答案 27 :(得分:5)

无,除了您不必两次写入类型名称。 http://msdn.microsoft.com/en-us/library/bb383973.aspx

答案 28 :(得分:5)

在大多数情况下,输入它更简单 - 想象

var sb = new StringBuilder();

而不是:

StringBuilder sb = new StringBuilder();

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

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

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

答案 29 :(得分:5)

从我昨天写的代码中可以看出事情变得更简单了:

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

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

附录:使用真实类型推断(例如F#)的语言花费一点时间将显示编译器在获得正确的表达类型方面有多好。它当然意味着我倾向于尽可能多地使用var,并且使用显式类型现在表明该变量不是初始化表达式的类型。

答案 30 :(得分:5)

我曾经认为var关键字是一个很棒的发明,但我对它进行了限制

  • 只有在显而易见的情况下才使用var(不滚动或查看返回类型)

我意识到这一点然后没有给我带来任何好处,并从我的代码中删除了所有var关键字(除非他们是特别需要的),现在我认为它们使代码的可读性降低,特别是对于其他读取代码的人来说。 / p>

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

答案 31 :(得分:5)

我将var分布在所有地方,对我来说唯一可疑的地方是内部短片,例如我更喜欢int i = 3;而不是var i = 3;

答案 32 :(得分:4)

使用LINQ另一个使用var的非常好的理由是编译器可以更多地优化查询。

如果您使用静态列表来存储结果,它将在您将其分配给列表的位置执行,但使用var它可能会将原始查询与代码中的后续查询合并,以便对其进行更优化的查询数据库中。

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

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

然后在循环中它添加了一个额外的连接,我没有在那里获取我原来包含的数据。

经过测试证明效率更高。

如果我们没有使用var它完全按照我们编写的那样提出了查询。

答案 33 :(得分:3)

作为Java专业人士,我在C#世界中相当新。我最初的想法是“哦不!有排水管安全”。但是,我读的var越多,我就越喜欢它。

1)Var是一个类型安全的,就像显式声明的类型一样。这都是关于编译时语法糖的。

2)遵循DRY的原则(不要重复自己)。 DRY就是避免冗余,而双方的类型命名肯定是多余的。避免冗余就是让您的代码更容易更改。

3)至于知道确切的类型..好吧..我认为你总是有一个大概的想法是你有一个整数,一个套接字,一些UI控件,或者其他什么。 Intellisense将从这里引导您。了解确切类型通常无关紧要。例如。我认为99%的时间你不关心给定变量是long还是int,float还是double。对于最后1%的情况,只需将鼠标指针悬停在var关键字上方。

4)我已经看到了一个荒谬的论点,现在我们需要回到1980式匈牙利疣,以区分变量类型。毕竟,这是在蒂莫西·道尔顿扮演詹姆斯·邦德的时代告诉变量类型的唯一方法。但这是2010年。我们已经学会根据它们的用法和内容命名我们的变量,并让IDE指导我们的类型。只要继续这样做,var就不会伤害你。

总而言之,var不是一件大事,但它是一件非常好的事情,而且Java很快就能复制出来。反对的所有论据似乎都基于IDE之前的谬误。我会毫不犹豫地使用它,我很高兴R#帮助我这样做。

答案 34 :(得分:3)

尽可能使用var

如果你的代码写得很好(即好的变量名,注释,清晰的结构等),本地变量的实际类型应该无关紧要

答案 35 :(得分:3)

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

好: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方法的期望 - 您说它希望它返回的行为类似于列表。在第二个例子中,这种期望是隐含的,而不是从代码中立即显而易见的。

很有意思(对我来说)很多pro-var参数说“我不关心它返回什么类型”,但继续说“我只需要迭代它......”。 (所以它需要实现IEnumerable接口,暗示类型 重要)。

答案 36 :(得分:3)

有人不喜欢对var的批评..所有的答案都下来了..哦,好吧..

@Jon Limjap: 我知道。 :)我的意思是可读性降低,就像在VB6中一样。我不喜欢依靠Intellisense来确定给定变量的类型。我希望能够单独使用源代码解决这个问题。

命名约定也没有帮助 - 我已经使用了好名字。我们要回到前缀吗?

答案 37 :(得分:3)

当我开始使用 var 关键字时,我也有同样的担忧 但是我随着时间的推移习惯了它,而不是回到显式变量类型。 Visual Studio的编译器\ intellisense在使用隐式类型变量工作方面做得非常好。

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

似乎是同样的问题,比如“我在变量名中使用前缀?” 坚持使用好的变量名,让编译器考虑变量类型。

答案 38 :(得分:3)

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

答案 39 :(得分:3)

嗯,这个人几乎都会被置之不理,但我会试着对此发表看法 - 尽管我认为我的观点如此混乱,以至于你可能不会从中得到很多。

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

对于更简单的类型,但是,整数,长整数,字符串 - 等等 - 我倾向于使用正确的类型。主要是因为它有点像一个“懒人的工具”,我在这里看不到太多的收获,很少有击键和它后来可能提供的混乱,这是不值得的。特别是浮点数(float,double,decimal)的各种类型让我感到困惑,因为我对文字中的后缀并不坚定 - 我喜欢在源代码中看到类型。

话虽如此,如果类型更复杂和/或在赋值的右侧明确重复,我倾向于使用var alot。这可以是List<string>等,例如:

var list = new List<string>();

在这种情况下,我认为没有必要重复两次类型 - 尤其是当你开始更改代码并且类型发生变化时 - 泛型类型可能会变得越来越复杂,因此必须更改它们两次只是痛苦但是,当然如果您希望针对IList<string>进行编码,则必须明确命名该类型。

总之,我做了以下几点:

  • 当类型较短或无法从上下文中读取时明确命名类型
  • 必须使用时使用var(duh)
  • 当var(在我看来)不会影响可读性时,使用var是懒惰的

答案 40 :(得分:3)

这纯粹是一种便利。编译器将推断出类型(基于右侧表达式的类型)

答案 41 :(得分:2)

到目前为止还没有注意到这一点,但是var用于foreach循环变量是常识。

如果您指定了特定类型,则编译器可能会以静默方式将运行时强制转换为您的程序!

foreach (Derived d in listOfBase)
{

以上将编译。但是编译器会将Base的向下转换为Derived。因此,如果列表中的任何内容在运行时不是Derived,则会出现无效的强制转换异常。型号安全性受损。看不见的演员是可怕的。

排除这种情况的唯一方法是使用var,因此编译器会从列表的静态类型中确定循环变量的类型。

答案 42 :(得分:2)

除了可读性问题外,使用'var'还有一个真正的问题。当用于定义稍后在代码中分配的变量时,如果用于初始化变量的表达式的类型更改为更窄的类型,则可能导致代码损坏。通常,重构一种方法以返回比以前更窄的类型是安全的:例如用某个类'Foo'替换返回类型的'Object'。但是如果存在一个基于该方法推断出其类型的变量,那么更改返回类型将意味着可以更长时间地为该变量分配一个非Foo对象:

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

所以在这个例子中,更改getFoo的返回类型会使getNonFoo的赋值变得非法。

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

正是出于这个原因,当我们为Curl编程语言(在Curl中称为“def”)添加类似的类型推理功能时,我们阻止了对使用此语法定义的变量的赋值。

答案 43 :(得分:2)

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

答案 44 :(得分:2)

我认为你可能误解了C#中var的用法。 仍然是强类型,与VB varient类型不同,因此使用它不会影响性能。

由于对最终编译的代码没有影响,因此它确实是造型师的选择。我个人不使用它,因为我发现代码更容易阅读定义的完整类型,但我可以想象几年后,完整类型声明将以与匈牙利符号现在相同的方式查看 - 额外打字对于intellisense默认提供的信息没有任何实际好处。

答案 45 :(得分:2)

边缘案件附近肯定存在分歧,但我可以告诉你我的个人准则。

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

  • 变量的类型明显 [来自人类]来自上下文
  • 变量的确切类型不是特别相关 [对人类]
    [e.g。你可以弄清楚算法在做什么而不关心你正在使用什么样的容器]
  • 类型名称很长并且会中断代码的可读性(提示:通常是通用的

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

  • 类型名称相对较短且易于阅读(提示:通常不是通用的
  • 初始化程序名称
  • 中的类型不明显
  • 确切类型对于理解代码/算法非常重要
  • 在类层次结构中,当人类无法轻易判断正在使用层次结构的哪个级别时

最后,我绝不会将var用于原生价值类型或相应的nullable<>类型(intdecimalstringdecimal? ,...)。有一个隐含的假设,如果你使用var,必须有“理由”。

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

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

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

答案 46 :(得分:2)

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

他们说继续,所以我使用它。

据说,我避免在类型需要调查的地方使用它,如下所示:

var a = company.GetRecords();

现在它可能只是个人的东西,但我立即无法查看它并确定它是Record对象的集合还是表示记录名称的字符串数组。无论哪种情况,我认为显式声明在这样的实例中都很有用。

答案 47 :(得分:2)

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

如果一个方法足够大,你无法跟踪该方法中的单个变量,那么你做的其他错误会使得任何批评变得苍白无比。

实际上,var的一个很好的论据是它可以使重构变得更简单,因为你不再需要担心你的声明过于严格(即当你应该使用IList&lt;&gt;时使用List&lt;&gt; ,或IEnumerable&lt;&gt;)。您仍然需要考虑新方法签名,但至少您不必返回并更改您的声明以匹配。

答案 48 :(得分:2)

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关键字正在做什么,并且这两个示例都倾向于通过使其更轻松来提高可读性,并使程序员编写有效代码变得更加愉快。 / p>

答案 49 :(得分:1)

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

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

一遍又一遍

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

当我试图消化代码时。我认为这在某种程度上归结为个人偏好。我会依赖常识 - 保存重要内容的执行标准(安全性,数据库使用,日志记录等)

-Alan。

答案 50 :(得分:1)

在我们的办公室,我们的首席技术官明确禁止使用var关键字,原因与您所声明的相同。

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

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

IEnumerable<TypeReturnedBySelectObject>

答案 51 :(得分:1)

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

在我的实践中,我发现变量类型对我来说只是在我在代码中使用它时才有意义。

如果我在 someVar 编译器上尝试做一些不适当的操作,请高兴地给我一个错误\警告。

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

答案 52 :(得分:1)

我在以下情况下使用var:

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

    var emp = new Employee();

  3. 显然我们想要一个Employee(因为我们正在创建一个新的Employee对象),所以如何

    Employee emp = new Employee() any more obvious?
    

    当无法推断出类型时,我不使用var,例如

    var emp = GetEmployee();
    

    因为返回类型不是很明显(在Employee,IEmployee,与Employee对象完全无关,等等?)。

答案 53 :(得分:1)

我必须同意Matt Hamilton

当使用良好的变量名时,Var可以使您的代码更具可读性和可理解性。但是var也可能使你的代码在Perl使用不当时无法阅读和理解。

var的好坏用途列表也没有多大帮助。这是常识的一个案例。更大的问题是可读性与可写性之间的问题。许多开发人员不关心他们的代码是否可读。他们只是不想输入那么多。就个人而言,我是一个阅读&gt;写伙伴。

答案 54 :(得分:1)

var也不错。记住这一点。 var也不错。重复。 var也不错。记住这一点。 var也不错。重复。

如果编译器足够聪明,可以从上下文中找出类型,那么你也是如此。您无需在声明时将其写下来。 intellisense使得更不必要。

var也不错。记住这一点。 var也不错。重复。 var也不错。记住这一点。 var也不错。重复。

答案 55 :(得分:1)

kronoz - 在这种情况下(两者都重载)会有关系吗?如果你有两个带有不同类型的重载,你基本上会说它们可以传递并做同样的事情。

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

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

答案 56 :(得分:1)

我不明白为什么人们会这样开始辩论。它真的没有任何目的,只能在当时没有获得任何东西的情况下开始火焰战争。现在,如果C#团队试图逐步淘汰另一种风格,我可以看到有理由争论每种风格的优点。但由于两者都将保留在语言中,为什么不使用更喜欢的那个,让每个人都这样做。这就像使用每个人最喜欢的三元运算符:有些喜欢它,有些喜欢它。在一天结束时,它对编译器没有任何影响。

这就像与你的兄弟姐妹争论哪一个是你最喜欢的父母:除非他们离婚,否则无关紧要!

答案 57 :(得分:1)

在我看来,使用var时没有问题。它不是自己的类型(您仍在使用静态类型)。相反,它只是节省时间,让编译器弄清楚要做什么。

与任何其他时间保护程序(例如自动属性)一样, 是一个好主意,在任何地方使用之前都要了解它是什么以及它是如何工作的。

答案 58 :(得分:1)

因冗余原因而被删除。

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();

是的,如果很难从名称和用法中确定变量的类型,请务必明确声明其类型。

答案 59 :(得分:1)

我认为人们不理解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”

答案 60 :(得分:1)

在这次讨论中迟到了,但我想补充一点想法。

对于那些反对类型推断的人(因为这就是我们在这里真正谈论的),那么lambda表达式呢?如果你坚持总是明确声明类型(匿名类型除外),你如何处理lambdas? “不要让我使用鼠标悬停”参数如何适用于var但不适用于lambdas?

<强>更新

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

答案 61 :(得分:1)

大多数人都在忽视:

var something = new StringBuilder(); 

通常不会像

那样快速输入
StringBuilder something = KEY'TAB'();

答案 62 :(得分:1)

一个很好的论据,为什么vars不应该仅仅用作“打字快捷方式”,而应该用于它们主要用于的场景:Resharper(至少v4.5)如果是的话,找不到类型的用法表示为var。在重构或分析源代码时,这可能是一个真正的问题。

答案 63 :(得分:1)

有时编译器也可以推断出比开发人员“更好”所需要的东西 - 至少是一个不了解他所使用的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 to SQL,示例1将会 将Person对象的整个结果集返回,然后在客户端进行过滤。 然而,示例2将在服务器上执行查询(例如在带有SQL的Sql Server上),因为编译器足够聪明,可以确定Where函数应该采用Expression&gt;而不是一个Func。

示例1中的结果也将无法在服务器上进一步查询,因为返回了IEnumerable,而在示例2中,如果结果应该是IQueryable而不是IEnumerable,则编译器可以计算出

答案 64 :(得分:1)

您可以让编译器(以及接下来维护代码的人)从初始化程序赋值的右侧推断出类型。如果这种推断是可能的,编译器可以这样做,这样就可以节省一些打字。

如果对那个可怜的家伙来说推理很容易,那么你就不会有任何伤害。如果推理很难,那么您已经使代码难以维护,因此作为一般规则 我不会这样做。

最后,如果您希望该类型是特定的,并且您的初始化表达式实际上具有不同的类型,则使用var意味着您将更难找到诱导的错误。通过明确地告诉编译器您想要的类型,当类型不是那样时,您将立即获得诊断。通过对类型声明进行反弹并使用“var”,您将不会在初始化时出错;相反,你会在某个使用var表达式指定的标识符的表达式中得到一个类型错误,并且更难理解为什么。

所以道德是,谨慎使用var;你通常不会做自己或你的下游同事维护者很多好。并且希望他以相同的方式推理,所以你不会因为猜测使用var而很容易猜测他的意图。在对具有较长寿命的系统进行编码时,优化您键入的数量是错误的。

答案 65 :(得分:1)

如果您知道类型,请使用类型。 如果您不知道类型,为什么不呢? 如果您不知道类型,那没关系 - 您找到了唯一有效的用途。

我很抱歉,但如果你能做的最好的事情是“它使代码全部排好”,那不是一个好的答案。找到一种格式化代码的不同方法。

答案 66 :(得分:0)

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

如果您是唯一的受众群体,或者您的受众对使用var感到满意,或者您对代码非常熟悉,那么我认为这无关紧要。如果您使用它: var s = new SqlConnection()那么它在很大程度上并不重要,可能会提高代码的可读性。如果人们不太挑剔,他们可以做一些工作来了解不明显的类型(在大多数情况下不需要,在下面的陈述中如何使用它通常可以解释一切)然后就可以了

但是,如果你有挑剔,心胸狭窄的队友喜欢抱怨,或者如果你的公司的设计指南明确禁止在类型不明显时使用var,那么你很可能会遇到强烈反对。

如果使用var会让您的代码难以阅读,那么即使可能是您的应用程序设计,也可能会使用var进行拍摄。

如果var引入了歧义(有点像你的IEnumerable / IEnumerable示例),那就不要使用它并且要明确。但var确实有其便利性,在某些情况下,恕我直言,甚至通过减少混乱来提高可读性。

答案 67 :(得分:0)

没错,但可能不合适。有关示例,请参阅所有其他回复。

var x = 5; (坏)

var x = new SuperDooperClass(); (好)

var x =来自db.Something中的t选择新的{Property1 = t.Field12}; (优于)

答案 68 :(得分:0)

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

答案 69 :(得分:0)

“你唯一可以真正说出我的口味的是,它是老式的,而且你的时间也是如此。” -Tolkien。

答案 70 :(得分:0)

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

// z编译为int

var z = 100;

// s编译为

下面的字符串
var s = "Hello";

// a编译为int []

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

// expr编译为IEnumerable //或者也许是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关键字将解析为该类型名称,并且不会被视为隐式类型的局部变量声明的一部分。

答案 71 :(得分:0)

Eric在这里的回答......

Namespace scoped aliases for generic types in C#

是相关的。

部分问题是C#中没有强类型别名。许多开发人员使用 var 作为部分代理。

答案 72 :(得分:0)

首先

var不是类型,也不是某些特殊功能(如c#4.0 dynamic)。它只是一种语法糖。您要求编译器通过右侧表达式推断类型。唯一必要的地方是匿名类型。

我认为使用var并不是好事或坏事,而是编码风格。我个人不使用它,但我不介意其他团队成员使用它。

答案 73 :(得分:0)

您不必写出类型名称,因为在编译时解析了类型,所以不会降低性能。

答案 74 :(得分:0)

来自Essential 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;

显式声明范围变量的类型会强制对LINQ Cast运算符进行幕后调用。此呼叫可能会产生意想不到的后果,并可能会影响性能。如果你遇到LINQ查询的性能问题,那么像这里显示的那样的演员是开始寻找罪魁祸首的一个可能的地方。 (此规则的一个例外是当你使用非通用的Enumerable时,在这种情况下你应该使用强制转换。)

答案 75 :(得分:0)

我不认为var per say是一种可怕的语言功能,因为我每天都会使用像Jeff Yates所描述的代码。实际上,几乎每次我使用var都是因为泛型可以制作一些非常冗长的代码。我生活冗长的代码,但泛型使它迈出了一大步。

那就是说,我(显然......)认为var已经成熟,可能会被滥用。如果代码在一个废弃的变量的方法中达到20多行,你将很快使维护成为一场噩梦。另外,教程中的var非常直观,在我的书中通常是一个巨大的禁忌。

另一方面,var是一个“简单”的功能,新程序员将会抓住并喜欢它。然后,在几分钟/小时/天内,当他们开始达到极限时遇到了巨大的障碍。 “为什么我不能从函数中返回var?”那种问题。此外,向强类型语言添加伪动态类型可以轻松地使新开发人员绊倒。从长远来看,我认为var关键字实际上会让c#更难为新程序员学习。

那就是说,作为一名经验丰富的程序员,我确实使用var,主要是在处理泛型时(显然是匿名类型)。我坚持我的观点,我相信var将是最受滥用的c#功能之一。

答案 76 :(得分:0)

当你不想重复自己时,

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;

答案 77 :(得分:0)

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

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

答案 78 :(得分:0)

取决于,不知何故,它使代码看起来“更干净”,但同意它让...更难以理解......

答案 79 :(得分:0)

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

但尚未测试它是否会这样做。

答案 80 :(得分:0)

我不使用var,因为它违背了C# - C / C ++ / Java的根源。虽然它是一个编译器技巧,但它使语言感觉它的类型不那么强。也许20多年的C已经将它们全部植入我们(反变种人)的头部,我们应该在平等的左侧和右侧都有类型。

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

foreach (var s in stringArray)
{

}

节省3个字符!

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

答案 81 :(得分:0)

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

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

var i = 5;
int j = 5;

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

......完全是主观的。

Implicit typing意味着使用var关键字声明的任何变量都没有运行时惩罚,所以它归结为关于是什么让开发人员满意的争论。

答案 82 :(得分:0)

@Keith -

  

在你的比较中   IEnumerable的&LT; INT&GT;和   IEnumerable的&LT;双&GT;你不需要   担心 - 如果你传递错误的类型   你的代码无论如何都不会编译。

这不太正确 - 如果方法被重载到IEnumerable&lt; int&gt;和IEnumerable&lt; double&gt;那么它可能会默默地将意外的推断类型(由于程序中的其他一些变化)传递给错误的重载,从而导致错误的行为。

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

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

答案 83 :(得分:0)

@erlando,

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

至于代码审查,我发现 var 关键字没有大问题。在代码审查期间,我更喜欢检查代码逻辑而不是变量类型。当然,可能存在开发人员可能使用不合适类型的情况,但我认为这种情况的数量非常少,这不是我停止使用 var 关键字的原因。

所以我重复我的问题。 为什么会对变量类型产生影响?

答案 84 :(得分:-1)

不要使用它,使你的代码不可读。

总是使用尽可能严格的打字,拐杖只会让你的生活充满生机。

答案 85 :(得分:-5)

如果你是懒惰的并且使用var来代替匿名类型以外的任何东西,你应该要求在命名这些变量时使用匈牙利表示法。

var iCounter = 0;

生命!

男孩,我想念VB。