var 关键字的意义何在? [复制]

Posted

技术标签:

【中文标题】var 关键字的意义何在? [复制]【英文标题】:What's the point of the var keyword? [duplicate] 【发布时间】:2010-09-17 13:48:43 【问题描述】:

var 关键字消除了对显式类型声明的需要,我感兴趣地阅读了 SO discussion 什么时候可能合适。

我还阅读了(但未使用)Boo,它似乎更进一步,将其设为optional to declare a local variable。使用 Boo,类型和声明都可以隐含。

这让我想知道,为什么 C# 语言设计者要费心包含一个 var 关键字?

更新:是的,var 支持匿名类型,但匿名类型本身不需要 var 关键字...

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

anon = new  Name = "Terry", Age = 34 ;

【问题讨论】:

我不会用 10 米长的杆子碰它。好吧,除了说我同意你的看法。我也不明白。 :) 呃,你的第二行示例在 c# 中的有效代码如何? @Pauli Østerø - 不是,问题(早已回答)是为什么不呢? Boo 似乎已经死了。你在那里读到了什么?也许应该更好地解释这一点,而不是从死 URL 中猜测出来。 【参考方案1】:

我相信 var(和其他几个新关键字)是专门为支持 Linq 而添加的。

var 是用于创建匿名类型的关键字 - 参见 http://msdn.microsoft.com/en-us/library/bb397696.aspx

匿名类型可以用在 Linq 以外的其他地方。

var 对于 Linq 非常有用。事实上,根据一位专家作者的说法,“Without ‘var’, LINQ gets too painful to use.”

【讨论】:

【参考方案2】:

对于匿名类型,其中包括支持 LINQ。

http://www.blackwasp.co.uk/CSharpAnonTypes.aspx

【讨论】:

【参考方案3】:

如果没有 var 关键字,当您实际上打算使用已经存在的变量时,可能会意外地创建一个新变量。例如

name = "fred";
   ...
Name = "barney"; // whoops! we meant to reuse name

【讨论】:

拥有 var 也会阻止您意外重用变量,因为 var name = "fred"; .... var name = "barney";可以被编译器发现。 这个答案混淆了两个不同的问题:“为什么在需要你声明变量的语言中有 var”和“为什么要声明变量?”通过强制声明它们来防止意外创建变量重用。 太棒了!感谢那。我一直在想这个问题,当我读到这个答案时,我觉得真的很愚蠢。【参考方案4】:

这有点主观,但我认为将 C# 3.0 设计为对隐式类型变量使用“var”关键字而不是没有关键字会使代码更具可读性。例如,下面的第一个代码块比第二个代码块更具可读性:

变量的声明位置很明显:

var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

变量声明的地方不明显:

myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

这些都是过于简单化的例子。我想你可以看到这是怎么回事。在复杂的情况下,能够找到实际定义变量的位置可能会很好。

【讨论】:

【参考方案5】:

更新:这里有两个相关的问题,实际上: 1. 为什么我必须声明变量? 2. 让你声明变量的语言中的“var”有什么用?

(1)的答案很多,可以在其他地方找到这个问题的答案。我对(2)的回答如下:

正如其他评论者所说,LINQ 将其用于其匿名类型。但是,LINQ 实际上是一个更普遍的问题的实例,其中表达式右侧的类型对于程序员来说要么是未知的,要么是非常冗长的。考虑:

SomeGeneric<VeryLongTypename<NestedTypename>> thing = new   
SomeGeneric<VeryLongTypename<NestedTypename>>();

冗长且容易出错,对吧?所以现在他们让你这样做了:

var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();

通过减少信息重复,消除错误。请注意,这里不仅仅是输入错误:左侧表达式的类型可能会被错误输入,编译器可以默默地从左向右转换,但转换实际上丢失了一些属性右值。当右值返回的类型可能未知或匿名时,这一点更为重要。

【讨论】:

C# 不是 Boo。它不支持鸭子打字。 C# 编译器根据分配给它的对象的类型来确定 var 声明的变量的类型 - 如果类型未知,则无法使用 var。需要匿名类型,因为 程序员 无法指定类型(但 C# 编译器可以)。【参考方案6】:

免责声明:我的示例是 Java,因为这是我所知道的,但概念应该相同。

我对我认为很关键的答案投了赞成票(很容易意外创建新变量)。

bill=5;
bi11=bill+5

账单的价值是多少?

也就是说,我有时觉得打字有点烦人:

DataOutputStream ds=new DataOutputStream();

看起来是多余的,但老实说,这并没有什么问题。无需再键入两次,而且非常有帮助。当您有疑问时需要时间——当您不确定如何使用某些 API 时。如果两次键入该类型声明确实让您感到困扰,那么您为什么要在这里浪费时间呢?自从您开始阅读本文以来,您可能已经输入了 30 或 40 个声明,足以满足您接下来两周需要的每个声明。

我想我的意思是,虽然我理解重复自己可能会造成的情绪压力,但一致性、清晰性和制作更智能工具的能力使其非常值得。

还有一件事,大多数时候代码不应该像我上面的例子。你应该做的是:

DataOutput ds=new DataOutputStream();

这会立即隐藏您在模板中使用具体类的事实。该模板应该能够在您的班级上执行您需要的所有操作。稍后,如果您想用其他类型的输出流替换 ds,只需更改该单行即可修复它。如果您通过转换为 DataOutputStream 来使用 DataOutput 不可用的功能,编辑器会很容易地找出并通知您。

【讨论】:

感谢billbil1 的示例……是的,这就是为什么要在使用之前声明事物的关键。【参考方案7】:

在您的问题中,var 通过告诉编译器单词anon 现在可以合法地在您希望看到赋值中隐含的类型的项目的任何地方使用来增加代码的价值。像这样要求向编译器引入名称允许编译器拒绝它没有明确告知允许的东西,从而在编译时捕获某些类型的错误,这样它们就不会在运行时崩溃。

例如,在您问题的更新部分,您询问了这个 sn-p:

anon = new  Name = "Terry", Age = 34 ;

以这种方式允许它的问题在于,它会将任何先前不存在名称的赋值左侧的任何内容转换为变量声明,即使它确实是一个错字。如果稍后在程序中为 anon 分配其他内容,然后进一步引用新值,但中间语句有错字,那么您将遇到一个直到运行时才会出现的问题。

您的回答是 Boo 做到了,所以它一定没问题或至少是可能的。但这是一个红鲱鱼。我们谈论的是 C#,而不是 Boo。 C# 的目的之一是拥有一种编译器可以捕获尽可能多的错误的语言。 Boo 也想这样做,但它也希望更像 Python。因此,它牺牲了一些(不是全部)C# 的编译时安全性,以换取类似于 python 的语法。

【讨论】:

没有一些例子我花了一些时间来解开你提到的错字问题但是是的,现在在使用它们之前声明所有变量绝对有意义(明确输入或使用var) ... 几天来,我一直在想和@EdGuiness 相同的问题,寻找反例,我现在感觉被释放了:)。【参考方案8】:

我了解对 var 的需求,它非常有用。没有关键字并且只是在没有类型的情况下动态定义变量是可怕的。如果您需要返工一年多未接触过的代码,您会伤害下一个必须维护您的代码的人或您自己。我不确定那是一扇应该在 C# 中打开的门,我希望它不会因为 var 在不必要的情况下过度使用而导致可读性问题。

我最近看到的几乎每个 .net 3.5 示例都使用 var 定义了所有变量。

我的论点是,它确实牺牲了可读性,以便在过度使用时节省击键。例如:

// What myVar is, is obvious
SomeObject myVar = new SomeObject();

// What myVar is, is obvious here as well
var myVar = new SomeObject();

我看到的问题是人们到处都在使用它……例如:

// WTF is var without really knowing what GetData() returns?
// Now the var shortcut is making me look somewhere else when this should
// just be readable!
var myVar = GetData();

// If the developer would have just done it explicitly it would actually
// be easily readable.
SomeObject myVar = GetData();

所以下一个争论是,只是更好地命名函数......

var weight = GetExactWeightOfTheBrownYakInKilograms();

仍然不知道什么会回来。它是 int、decimal、float、weight 对象,什么?我仍然不得不浪费时间查找它......需要智能拐杖来拯救我懒惰的编程。也许在函数名中包含返回类型。好主意,现在使用 var 并没有为我们节省什么,只是让我的所有函数都有真正的长名称。

我认为人们只是过度使用 var 并且它会导致懒惰的编程,进而导致更难阅读代码。每次输入关键字 var 时,都应该有充分的理由使用它而不是显式地使用它。

【讨论】:

我喜欢 GetExactWeightOfTheBrownYakInKilograms()。 每次你在等号两边都输入类型,你只是因为不使用var而浪费了击键。 @Pauli 这不是她/他所提倡的。 这为我澄清了一些事情。我想确保我没有遗漏为什么使用它。我从这个和其他答案中得到的是:很少使用它,如果你这样做,请确保它是清晰的。 如何对付顽固的开发人员,他们认为在任何地方使用“var”是微软的首选方式?它激怒了我。我无法一目了然地阅读他们的代码,并且需要两倍的时间才能弄清楚发生了什么。我不明白他们几个月后是如何阅读自己的代码的。【参考方案9】:

有时字体很大。想象一下您在字典中拥有具有泛型类型的字典的类型。 var 将使这更具可读性。 它也是一种编码实践。

此外,如果您想创建匿名类型,例如 var randomData = Id = 1, name = "Amit"

我个人使用类型,因为有时您需要知道函数返回什么(以防万一,您想将结果传递给其他函数。)。比将光标悬停在 var 上更容易查看类型。 例如:var result = GetSomethign();

此外,有时您需要按 F12 导航到类型。这对于 var 是不可能的。当您处于调试模式时,这有点烦人,因为您在调试时看不到类型。您需要停止调试,查看类型并重新开始调试。

【讨论】:

以上是关于var 关键字的意义何在? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

当 ++i“可以”在 c++ 中更快时,i++ 的意义何在? [复制]

JavaScript - 在 for 循环中使用 let 和 var 关键字声明迭代变量有啥区别? [复制]

阿里程序员吐槽:玩命赚钱却抵不过游手好闲的拆迁户,奋斗的意义何在

javascript var或not var,有啥区别? [复制]

C#中的“var”是啥意思? [复制]

C# 3.0 中 var 关键字的优势 [重复]