C# var关键字在C语言中的使用

C# var关键字在C语言中的使用,c#,type-inference,var,C#,Type Inference,Var,在与同事讨论了在C3中使用“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(

在与同事讨论了在C3中使用“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.
很明显,它将是一个实现IEnumerable的类型,结果是什么,但是它并不像声明新对象的var那样明显

对于对象的LINQ,情况更糟,例如:-

var results = from item in someList
              where item != 3
              select item;
这并不比someList{/…}equivalent中的等效foreachvar项好多少

这里真正关心的是类型安全性——例如,如果我们将该查询的结果放入接受IEnumerable和IEnumerable的重载方法中,调用方可能会无意中传入错误的类型


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

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

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

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);
如果是这样的话:

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);
。。。这样,阅读代码的人就更有可能理解列表是什么。如果您可以控制列表变量本身的名称,那就更好了

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

var x = SaveFoo(foo);
。。。但这是有道理的:

var saveSucceeded = SaveFoo(foo);
我想每个人都有自己的。我发现自己在做这件事,简直是疯了:

var f = (float)3;

我需要一些12步var程序。我的名字是Matt,我滥用var。

我认为var的关键是只在适当的情况下使用它,即在Linq中执行它方便的事情时,以及可能在其他情况下使用它

如果你有一种类型的东西,那么你应该使用它-不这样做是简单的懒惰,而不是创造性的懒惰,这通常是被鼓励的-好的程序员经常非常努力地工作,懒惰,可以被认为是事情的根源在第一位

一个全面的禁令就像一开始滥用构造一样糟糕,但确实需要一个合理的编码标准

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

我怀疑这一个会跑啊跑-:


Murph

风险价值很难实现的一种特殊情况是:离线代码评审,尤其是书面代码评审

你不能依赖鼠标悬停来实现这一点。

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

var orders = cust.Orders;
我不在乎Customer.Orders是IEnumerable、ObservableCollection还是BindingList——我只想将该列表保存在内存中,以便对其进行迭代或稍后获取其计数或其他信息

将上述声明与以下内容进行对比:

ObservableCollection<Order> orders = cust.Orders;
对我来说,类型名称只是噪音。如果我回去决定改变客户的类型。订单从ObservableCollection到IList,那么我也需要改变声明——如果我一开始就使用var,我就不必这么做。

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


诚然,这可能意味着不清楚我们在处理什么类型的问题。那又怎么样?这实际上就是解耦设计的要点。在处理接口时,您显然对变量的类型不感兴趣。var更进一步,是的,但我认为从可读性的角度来看,参数仍然是一样的:程序员实际上不应该对变量的类型感兴趣,而是对变量的作用感兴趣。这就是为什么微软也将类型推断称为“鸭子类型”

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

如果我使用的是一个var声明的变量,并且对变量的用途感到困惑,那么我的代码就有一些根本性的错误。var不是原因,它只是让症状可见。不要责怪信使

现在,C团队发布了一个编码指南,指出var应该只用于捕获创建匿名OU的LINQ语句的结果 s类型,因为在这里,我们没有真正的选择来替代var。好吧,去他妈的。只要C团队没有给我一个合理的理由来支持这条准则,我就会忽略它,因为在我的专业和个人观点中,这纯粹是胡说八道。很抱歉我没有与所讨论的指导方针有关的链接


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

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


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

我看不出有什么大不了的

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!
你仍然对“某物”有完全的智能感知,对于任何模棱两可的情况,你都有单元测试,对吗?你知道吗

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

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);
并将总的思维混乱减少到:

var v = new List<somethinglongtypename>();
不错,不如:

v = List<somethinglongtypename>();

但这就是原因。

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

C的var非常酷,因为它看起来像动态类型,但实际上是静态类型——编译器强制执行正确的用法

变量的类型实际上并没有以前说过的那么重要。从上下文来看,它应该相对清楚它与其他变量和方法的交互以及它的名称-不要期望customerList包含一个int


我仍在等待我的老板对此事的看法——我得到了一个全面的许可,可以在3.5中使用任何新的构造,但我们在维护方面会做些什么?

在IEnumerable和IEnumerable之间的比较中,你不必担心——如果你传递了错误的类型,你的代码无论如何都不会编译

不必担心类型安全性,因为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,它会出现类似IEnumerableI在所有位置拆分var的情况,对我来说唯一有问题的地方是内部短类型,例如,我更喜欢int I=3;超过var i=3

我们为人而不是机器采用了ethos代码,基于这样一个假设,即您在维护模式下花费的时间比在新开发上花费的时间长数倍

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

因此,

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

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

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

为什么要引入var关键字

有两个原因,一个是 存在于今天,一个将会出现的 在3.0中

第一个原因是该代码是 因为所有这些 冗余:

字典mylists=新字典

这是一个简单的例子——我 写得更糟。任何时候你都是被迫的 要输入完全相同的内容两次, 这是我们可以做到的冗余 去除写起来好多了

var mylists=新字典

然后让编译器知道是什么 类型基于分配

第二,C3.0引入了匿名 类型。因为匿名类型由 定义没有名称,您需要 能够推断出 初始化中的变量 表达式(如果其类型为匿名)

我的。整篇文章以及随后的文章都非常好


这就是var的用途。其他用途可能不会这么好用。任何与JScript、VBScript或动态类型的比较都是完全错误的。请再次注意,为了使某些其他功能在.NET中工作,需要使用var。

对我来说,对var的反感说明了为什么.NET中的双语很重要。对于那些同样做过VB.NET的C程序员来说,var的优势是显而易见的。标准C声明:

List<string> whatever = new List<string>();
但是,在VB.NET中没有人这样做。这将是愚蠢的,因为自从第一个版本的.NET哟 你能做到这一点

Dim whatever As New List(Of String)
…它创建变量并在一个合理紧凑的行中初始化所有变量。啊,但是如果你想要的是IList,而不是列表呢?在VB.NET中,这意味着您必须执行以下操作:

Dim whatever As IList(Of String) = New List(Of String)
就像您在C中必须做的那样,显然不能将var用于:


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

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

那些说“没关系,用你喜欢的东西”的人看不到全局。每个人都会在某个时刻学习别人的代码,并且必须处理他们在编写代码时做出的任何决定。要处理完全不同的命名约定,或者-经典的抱怨-支撑风格,而不在组合中添加整个“var或not”的东西,已经够糟糕的了。最糟糕的情况是,一个程序员没有使用var,然后出现了一个喜欢它的维护人员,并使用它扩展了代码。所以现在你有一个邪恶的混乱

标准确实是一件好事,因为它们意味着您更有可能拾取随机代码,并能够快速搜索它。不同的事情越多,事情就越难处理。而转向“var everywhere”风格会带来很大的不同

我不介意动态类型,也不介意隐式类型——用专门为它们设计的语言。我很喜欢Python。但是C被设计成一种静态显式类型的语言,这就是它应该保持的状态。打破匿名类型的规则已经够糟糕的了;让人们更进一步,更进一步地打破这种语言的习惯用法,这是我不高兴的事情。既然妖怪从瓶子里出来了,它就再也不会回到瓶子里了。C将被分割成几个营地。不好。

从:

不幸的是,你和其他人都错了。虽然我同意你的观点,裁员不是一件好事,但解决这一问题的更好办法是采取以下措施:

MyObject m=新对象

或者,如果您正在传递参数:

人员p=新的姓氏,姓氏

其中,在创建新对象时,编译器从左侧而不是右侧推断类型。与var相比,它还有其他优点,因为它也可以用于字段声明。它还有一些其他方面也很有用,但我在这里不赘述

最终,它并不是为了减少冗余。不要误解我的意思,var在C中对于匿名类型/投影非常重要,但是这里的用法还远远不够,我已经说了很长很长时间了,因为你混淆了正在使用的类型。输入两次太频繁了,但是声明零次太少了

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

我想如果你主要关心的是必须少打字,那么就没有任何理由会动摇你使用它

如果你只想成为一个看你的代码的人,那么谁在乎呢?否则,在这种情况下:

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);
没关系,但在这种情况下:

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);
它短路了我的大脑可以从代码的“英语”开始形成的任何即时类型的演绎


否则,只需对可能需要参与您项目的其他人使用您最好的判断和编程“礼貌”。

我想这取决于您的观点。我个人从来没有因为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

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

考虑到Intellisense现在的强大功能,我不确定var是否比在类中包含成员变量或在方法中包含局部变量更难读取,而这些变量是在可见屏幕区域外定义的

如果您有一行代码,例如

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();
比以下内容更容易或更难阅读:

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

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

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }
如果没有var,这将是非常冗长的

附录:花一点时间在具有实类型推断的语言上,例如F,将显示编译器在正确获取表达式类型方面有多么出色。这当然意味着我倾向于尽可能多地使用var,现在使用显式类型表明变量不是初始化表达式的类型
e、

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

foreach (var c in list) { ... }
foreach (var customer in list) { ... }
List<somethinglongtypename> v = new List<somethinglongtypename>();
var people = Managers.People
var fc = Factory.Run();
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,我还必须不断更改左侧声明的类型。我知道它是次要的,但它非常方便。

没有,只是你不必写两次类型名

对于100%需要的匿名类型,您最有可能需要它;但它也避免了琐碎案例的重复,而且IMO使这条线更加清晰。对于一个简单的初始化,我不需要看到类型两次

例如:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();
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() { ... }
...

相反,您不必更改它。

对于认为var节省时间的afficionados,键入以下内容所需的按键次数更少:

StringBuilder sb = new StringBuilder();

数一数如果你不相信我

19对21

如果有必要,我会解释的,但是试试看。。。根据intellisense的当前状态,您可能需要为每一个输入更多的内容

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


我个人的感觉是,除非类型未知,否则不应使用var,因为它会降低代码中的识别可读性。大脑识别类型所需的时间比识别整行文字所需的时间更长。理解机器代码和比特的老前辈们确切地知道我在说什么。大脑并行处理,当你使用var时,你迫使它将输入序列化。为什么有人想让他们的大脑更努力地工作?这就是计算机的用途。

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


使用智能感知是否懒惰?它的打字比全名少。还是有一些工作较少但不值得批评的事情?我认为有,var就是其中之一。

不错,这更像是一种风格上的东西,往往是主观的。无论何时使用var,它都会增加不一致性

另一个值得关注的情况是,在下面的调用中,仅通过查看CallMe返回的代码类型是无法辨别的:

这是我对var的主要抱怨

当我在方法中声明匿名委托时使用var,不知何故,var看起来比使用Func更干净。考虑这个代码:

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

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

这两个都不是绝对正确的;var对可读性既有积极的影响,也有消极的影响。我认为,当下列任一情况为真时,应使用var:

类型是匿名的,您在这里没有任何选择,因为在本例中它必须是var 根据指定的表达式,该类型是明显的,即var foo=带有AreaAllyLongName的新类型无意义重复
var对性能没有影响,因为它是语法上的糖;一旦编译成IL,编译器就会推断类型并定义它;实际上,它并没有什么动态性。

Var,在我看来,在C中是一个好东西。任何这样类型的变量仍然是强类型的,但它从定义它的赋值的右侧获取其类型。因为类型信息在右侧可用,所以在大多数情况下,也必须在左侧输入它是不必要的,而且过于冗长。我认为这在不降低类型安全性的情况下显著提高了可读性

在我看来,从可读性的角度来看,为变量和方法使用良好的命名约定比显式类型信息更重要。如果我需要类型信息,我可以将鼠标悬停在VS中的变量上并获取它。但是,一般来说,读者不需要显式类型信息。对于开发人员来说,在VS中,无论变量如何声明,您仍然可以获得Intellisense。尽管如此,在某些情况下,显式声明类型还是有意义的——也许您有一个返回列表的方法,但您希望在方法中将其视为IEnumerable。为了确保您正在使用接口,声明接口类型的变量可以使其显式。或者,您可能想要声明一个没有初始值的变量——因为它会根据某种条件立即得到一个值 激动。在这种情况下,你需要的类型。如果类型信息有用或必要,请继续使用它。不过,我觉得通常情况下,这是不必要的,而且在大多数情况下,没有它,代码更容易阅读。

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

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

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();
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);
在需要的地方,即为匿名类型声明引用。 使代码更具可读性,即删除重复声明。
写出数据类型通常会使代码更容易理解。它显示了您正在使用的数据类型,这样您就不必首先通过了解代码的作用来了解数据类型。

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

我只在清楚使用什么类型时才使用var

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

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

var x = MyClass.MyFunction();
特别是,我从不在右边甚至不是一个方法,而只是一个值的情况下使用var:

var x = 5;


因为编译器不知道我是否需要在任何一个像样的IDE中使用byte、short、int或任何

,所以您不需要使用文本搜索来获取类的使用情况,而是让IDE根据它的解析树来完成,或者它标识对象的类型。因为我们讨论的是静态类型,所以除了匿名类型之外,其他都可以找到。我不喜欢在没有文档和自由使用var的情况下继承10万行源代码。特别是如果您将var与不太有用的变量名组合在一起。我认为它在说明某一点或处理匿名类型(但在生产代码中)时会有所帮助?Arnshea:您已经指出了真正的问题:无用的变量名和缺少的文档。我真的看不出var是什么造成了这种混乱。当然,在某些情况下,强调变量的类型/大小很重要,例如低级位操作。这很好:从来没有人声称var应该专门使用。规则很简单:如果它真的引起混乱,就不要使用它。我看到的每一个反对var的例子都假设程序员将使用无意义的变量名。但也许这就是为什么var比显式指定类型更好:它迫使程序员想出好的变量名。微软也将类型推断称为“duck typing”-真的吗?我会很震惊…你为什么要在纸上复习代码?想想那些树吧;您可以在不使用var的情况下遇到相同的问题;问题是变量名不正确。如果变量名选择得当,那么var的使用就无关紧要了。我的团队中有一个人通过打印代码来检查自己的代码,并查找bug。他的墙上满是密码。我有一次走进来,他有一个大白板,上面覆盖着他的调试练习。可能仅仅变量名并不能解决问题,除非你回到匈牙利符号,类型是名称的一部分。“something”的类型对编译器来说非常清楚,在内部,var被设置为“someMethod”的返回类型,编译器很清楚,但对于从事该项目的开发人员来说可能并不清楚。Boo在我身上迅速成长。不,v=List;甚至都不好。区分引入新变量和分配给现有变量是很重要的。如果您以前在当前范围内分配给“v”,那么它就是分配给现有变量。否则它将赋值给新变量“v”。简单,哇。忽略到目前为止在这篇文章中提出的所有论点,并重新设置整个讨论是一个相当大的成就。这100%描述了我对“var”的感受,特别是从获取其他人代码的角度来看。如果手头的任务到处都是,那么使用var将从根本上改变它+var f=float3的唯一错误是:;是的,它应该是var f=3f或var f=3.0,因为单精度很糟糕。呵呵,是的,3f或3.0是最好的选择!我们这些狂热分子必须团结一致!第一个示例中的真正问题是list,而不是c。什么清单?该列表应重命名为customers、CustomerWhowoney、currentCustomers或更具描述性的名称。一旦你有了它,c可以保持原样,因为你已经知道它将包含什么。嗨,马特!我的名字是肯尼,我是一个瓦莱克迷//我觉得利珀特的论点很奇怪。没有人键入secon

d类名称,他们让Intellisense为他们编写,但随后他转过身,声称var更好,因为编译器/Intellisense可以解决这个问题。你不能两全其美!C团队不控制intellisense,他们控制编译器。无论如何,这不是主要问题。我认为var在单独保存键入时不会得到100分。@Dustman:var根本不保存键入。它让你写得更多!当我阅读代码时,我喜欢让显式类型出现在我面前。我怎么知道这里没有这个类型的客户订单?是的,我可以将鼠标悬停在上面来找出答案,但为什么我必须这样做呢但问题是,总的来说,这并不重要。提供的客户订单是你可以列举的东西,比如foreach,不管它是什么类型。额外的代码只是阻碍了阅读意图。但是如果您只需要cust.Orders是您可以枚举的东西,那么将其声明为IEnumerable并不能使该需求明确明了吗?将其声明为var意味着您实际上失去了该要求。@jon那么IEnumerbal orders=cust.orders foreachvar order in orders会有什么不同呢?IEnumerable说的唯一一件事是你可以把它放在foreach中,但你已经知道,从下面的一行中,IEnumerable说的唯一一件事是你可以把它放在foreach中,它还表达了你唯一可以做的事情是枚举的意图。使用var提供了对具体集合类型的公共成员的访问和智能感知。实际上,从另一个问题看来,这不是一个相当强的时间点。这是除了能够声明匿名类型之外,唯一实现它们的唯一原因。但他们可能会让var成为一个只针对匿名类型的特殊关键字。大概在.Net 4中,动态类型很常见,这将变得更重要?相反,如果你现在对var感到困惑,我希望你会对动态类型感到困惑。上帝禁止任何人声明一个动态,然后使用var引用它:我的意思是动态d=52;var x=d;你上面的例子并不是不使用var的理由;它们是使用好的描述性变量名的论据。如果您使用的不是[var fc=Factory.Run;],而是[bool fc=Factory.Run;],则代码不会变得更清晰。有关信息,您可以在任何情况下获得类似问题,其中这是一个隐式类型转换,您不希望在同一行中看到它两次。将来,在定义下面的if中声明变量后,可能不会直接创建变量,而可能无法直接明确变量的类型。大多数开发人员习惯于在行首直接看到类型,特别是在复杂代码中,您不想让阅读代码变得更困难。@TheVillageIdiot-我回滚了您的编辑,因为在这种情况下,hscroll与点相关-p@Gertjan-我的大脑有限;如果它很复杂,我不想看两遍,必须开始比较界面/具体/等等。我很高兴看到一次,并认为它是其中之一。同意-想知道为什么这个好的副作用没有在更流行的回答中被吹捧为其他一些更主观的优点。今天我就想到了。我有一个工厂类,它返回主菜单类的状态。今天,我创建了一个与MainMenu界面相同的MainMenu2。我有我的所有应用程序代码未动后的变化!你这么说很有趣,因为var可以使重构变得更简单。如果您已经使用了var,则不必这样做。现在,您可以始终依赖IDE的重构工具,但您知道,您也可以始终依赖IDE的类型:是的,编译器比我们更聪明,克服它吧!有趣的是,你提到双语是促进var使用的因素。我对var关键字的反感直接源于我对javascript的熟练程度!:C中的var与JavaScript中的var没有任何联系。C中声明的变量是强类型的。我发现stringBuilder sb=new stringBuilder的重复很混乱,而且很难清楚识别。这是额外的噪音。问题是,确定理解某些代码需要哪些额外的智力努力和哪些不需要额外的智力努力是相当主观的!除非类型未知,否则不应使用var…-您总是可以知道类型,就像编译器一样。这不是动态类型,它只是让编译器为您确定类型。但是类型从来都不是未知的。但是你真的需要知道那行的类型吗?你知道CallMe会返回一些东西;知道创建了名为variable的局部变量还不够吗?除非你扩展你的例子,否则这不是一个非常可靠的抱怨,依我看,这不是关于不冗长,而是关于不让编译器为你做语法糖。考虑这一点:var获取
ter…,现在是Func getter…,第二次你知道你不需要提供任何参数和它返回的内容。在设计或重构时,您从一开始就知道要做什么,并且可以更快地做出决策。掌握所有信息比多几个字符更重要。这只有在处理大量代码时才能理解。既然我们都在谈论visual studio,那么将鼠标悬停在变量上一秒钟,看看它是什么类型有什么大不了的?总比运行声明要好得多。泛型变量和函数名变量、CallMe都是不好的例子。然而,如果CallMe是某种电话应用程序中的函数,那么var call=CallMe。。。。挂断电话;会更有意义。@Randolpho:将鼠标悬停在变量上一秒钟,看看它是什么类型,有什么大不了的?它增加了维护开销的时间。。。加上1秒只是悬停时间,而不是计算键盘到鼠标上下文切换的次数。我不知道你的情况,但我的工作是有期限的。每次我必须悬停在一个变量上才能找出它是什么类型,这是我最好花在解决问题上的时间。两者都同意,尽管我对第二种情况有很长的限制,但如果一个类型有那么长,它通常是一个具有大量嵌套泛型参数的泛型类型,在这种情况下,一个强类型的ShortType相当于一个长名称的typewithareallylongname。没有意义上的重复会让更多的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的意义上的。我更喜欢一个非常长但非常精确的类型名,而不是一个缩写且可能模棱两可的较短类型名。我要补充一点,我也不同意人为地夸大名字的长度。如果5个字符创造了一个简洁的名字,清楚地表明了意图,那么就用5个字符,而不是25个字符。@Steve:我必须同意你的观点;创建一个简短的类型,我想你的意思是从特定的泛型类型继承,仅仅是为了缩短名称,这不是一个好的做法;它将要求您复制和传递泛型类型中的任何构造函数,并防止您将从泛型类型继承的其他类型传递给函数。如果不是继承,则像使用typedef一样使用继承。如果类型明显,则使用var?也许吧,但真正的收获是当类型无关紧要时。如果你在做一些事情,比如var customers=随便什么;var query=从客户中的c中选择内容,不管“客户”的确切类型是什么。很明显,你可以如何使用它,这就足够了。如果实际的类型很麻烦,那么就应该抑制它。@Kristofer:我可以理解想要消除标记的混乱,但是将它们包装到类中是不可接受的选择,因为这样就切断了该泛型类型的任何其他合法子类成为有效参数的可能性。我更愿意在文件顶部使用using ShortType=LongGenericType指令,因为它具有相同的可读性,不需要重新创建构造函数,也不需要将子类从候选类中删除。使用var很好,但我不必弄明白类型似乎是使用它的一个非常糟糕的原因。。。您应该知道类型是什么,var只是避免键入itvar i=0的快捷方式;==失败var c=新CrazyFrigingLongClassName;==赢Var还让我想起了VB/VBA变量类型。它也有它的位置。我记得很多年前,它的使用还不尽如人意,而且它相当消耗资源。var readabilityBeDamned=true;这里提到的所有示例的问题是,我们只看一行代码。当我看到一行又一行的var声明时,它就失控了。可读性是主观的,但我发现var的滥用远远超过了合理使用的程度。int和var是一个值得争论的问题,但多个嵌套泛型类型使var成为一个天赐之物。这就是反复使用类型名确实会破坏代码可读性的地方。这绝对是使用它的错误原因。如果代码使用嵌套泛型类型,则应为其派生特定的命名类。例如:类IntStringEnumerator:IEnumerable,然后使用新名称。这会清理代码并更好地描述类型。好吧,但我的示例只是夸大其词。IntStringEnumerator i=新的IntStringEnumerator仍然输入太多。我总体上同意。在我看来,这里的关键是要确保意图是明确的。如果团队中的大多数开发人员不清楚,那么这是有害的,没有帮助的。也就是说,我个人是这方面的超级粉丝,但当我团队中的其他开发人员难以确定我的意图时,我不得不克制自己。想想看。嗯,我发现左边的字体更容易阅读。使用ReSharper,我可以
“无论如何,我都不必在右边重新键入类型,所以我不会感到麻烦。@BlueRaja-我发现使用好的变量名通常可以省去理解实际类型的麻烦。”。Intellisense在var定义的变量上仍然可用,因此在编码时,我不需要知道选择方法/属性的类型。这与其说是关于何时编码,不如说是关于何时必须阅读代码。我必须站在厚边上,我需要有好的方法和变量名,以及对正在操作的类型的理解,才能正确理解我正在阅读的代码。我认为你是对的,尽管这是更大问题的征兆。信任的人。要确保代码正在做它看起来正在做的事情,您需要确保所使用的类型。+1,唯一需要注意的是var与Variant无关。如果右侧不够清楚,无法证明var的使用,那么var不是问题:右侧是问题。这还不够描述性。客户c=GetContext仍然不清楚,也不比使用var好多少。我发现代码是针对人而不是机器的,这是一个很好的指导原则-遵循它可以产生更好的代码,并有助于避免过早优化。我没有得到var list=new KeyValuePair?对我来说,一个列表可以包含更多的内容。代码是为人编写的,而不是为机器编写的-阿门。请在迭代之前去掉IQueriable:anonEnumeration.ToList@戴维迪兹,你能换个说法吗?你的话毫无意义。我的代码段中没有一个引用了IQueryable或.ToListvar anonEnumeration=from post,其中post.Date>oldDate让author=GetAuthor post.author选择new{PostName=post.Name,post.Date,AuthorName=author.Name};不返回IQueriable吗?@davidiez这取决于AllPosts返回的内容-询问者引用了列表,所以我假设是这样。在这种情况下,结果是anonEnumeration的类型为IEnumerable note no i In Queryable-但是在这种情况下,我的代码仍然有效,因为IQueryable实现了IEnumerable。关于它们之间的区别,这里有很多更好的Q&a——我的例子是‘a是匿名的,var允许你把它分配给一个静态类型的变量。哦,我明白了,感谢您的解释:我的评论是因为迭代IQueryable不是一个好的实践,因为在每次迭代中,您都在DB中生成read语句。在迭代之前,请确保*.ToList IQueryable's