提问人:Ed Guiness 提问时间:10/16/2008 最后编辑:Ed Guiness 更新时间:5/17/2021 访问量:20647
var 关键字的意义何在?[复制]
What's the point of the var keyword? [duplicate]
问:
var 关键字消除了对显式类型声明的需要,我饶有兴趣地阅读了 SO 关于何时合适的讨论。
我还读过(但未使用)Boo,它似乎更进一步,使声明局部变量成为可选。使用 Boo,类型和声明都可以隐含。
这让我不禁要问,为什么 C# 语言设计者要费心去包含 var 关键字呢?
更新:是的,var 支持匿名类型,但匿名类型本身并不需要 var 关键字......
var anon = new { Name = "Terry", Age = 34 };
对
anon = new { Name = "Terry", Age = 34 };
答:
我相信 var(和其他几个新关键字)是专门为支持 Linq 而添加的。
var 是用于创建匿名类型的关键字 - 请参阅 http://msdn.microsoft.com/en-us/library/bb397696.aspx
匿名类型可以在 Linq 以外的其他地方使用。
var 对 Linq 非常有用。事实上,根据一位专家作者的说法,“如果没有'var',LINQ 就会变得太痛苦而无法使用。"
对于支持 LINQ 的匿名类型。
http://www.blackwasp.co.uk/CSharpAnonTypes.aspx
如果没有 var 关键字,当您实际打算使用已经存在的变量时,可能会意外地创建一个新变量。例如
name = "fred";
...
Name = "barney"; // whoops! we meant to reuse name
评论
这有点主观,但我认为将 C# 3.0 设计为为隐式类型变量使用“var”关键字而不是 no 关键字会使代码更具可读性。例如,下面的第一个代码块比第二个代码块更具可读性:
很明显,在声明变量的位置:
var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;
在声明变量的位置不明显:
myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;
这些都是过于简单化的例子。我想你可以看到这是怎么回事。在复杂的情况下,能够找到实际定义变量的位置可能会很好。
更新:实际上,这里有两个相关的问题: 1. 为什么我必须声明变量? 2. “var”在让你声明变量的语言中有什么用?
(1)的答案很多,可以在其他地方找到这个问题。我对(2)的回答如下:
正如其他评论者所说,LINQ 将其用于其匿名类型。但是,LINQ 实际上是一个更普遍的问题的实例,其中表达式右侧的类型对程序员来说是未知的,或者非常冗长。考虑:
SomeGeneric<VeryLongTypename<NestedTypename>> thing = new
SomeGeneric<VeryLongTypename<NestedTypename>>();
冗长且容易出错,对吧?所以现在他们让你这样做:
var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();
通过减少信息重复,可以消除错误。请注意,这里不仅存在键入错误:左侧表达式的类型可能会被错误键入,以至于编译器可以静默地从左到右进行强制转换,但强制转换实际上会丢失右值的某些属性。当右值返回的类型可能是未知的或匿名的时,这一点就更为重要。
评论
免责声明:我的例子是 Java,因为这是我所知道的,但概念应该是相同的。
我投票支持了我认为至关重要的答案(不小心创建新变量太容易了)。
bill=5;
bi11=bill+5
账单的价值是多少?
也就是说,我发现有时打字有点烦人:
DataOutputStream ds=new DataOutputStream();
似乎是多余的,但老实说,它并没有真正的问题。输入两次不需要您花费的时间,而且非常有帮助。需要时间的是当你有问题时——当你不确定如何使用某些 API 时。如果键入该类型声明两次真的会打扰您,那么您为什么要在这里浪费时间呢?自从你开始阅读这篇文章以来,你可以输入30或40个声明,足以满足你接下来两周需要的每个声明。
我想我是说,虽然我理解重复自己可能造成的情绪压力,但一致性、清晰度和制作更智能工具的能力使它非常值得。
还有一件事,大多数时候代码不应该像我上面的例子一样。你应该做的是:
DataOutput ds=new DataOutputStream();
这会立即隐藏您在模板中使用具体类的事实。该模板应该能够对类执行所需的所有操作。稍后,如果您想用其他类型的输出流替换 ds,只需更改该行即可修复它。如果您通过强制转换为 DataOutputStream 来使用 DataOutput 不可用的功能,编辑器将很容易弄清楚并通知您。
评论
bill
bil1
在您的问题中,通过告诉编译器该单词现在是合法的,可以在您期望看到赋值中隐含的类型的项的任何地方使用,从而为代码增加价值。像这样要求向编译器引入名称允许编译器拒绝未明确告知允许的内容,从而在编译时捕获某些类型的错误,因此它们不会在运行时爆炸。var
anon
例如,在问题的更新部分,您询问了以下代码段:
anon = new { Name = "Terry", Age = 34 };
允许这样做的问题在于,它会将任何赋值左侧以前不存在的名称转换为变量声明,即使它确实是一个错别字。如果稍后在程序中将其他内容分配给 anon,然后进一步引用新值,但中间语句有拼写错误,那么您就遇到了一个问题,直到运行时才会出现。
你的回答是 Boo 做到了,所以它一定是可以的,或者至少是可能的。但这是一条红鲱鱼。我们谈论的是 C#,而不是 Boo。C# 的目的之一是拥有一种编译器可以捕获尽可能多的错误的语言。Boo 也想这样做,但它也想更像 Python。因此,它牺牲了部分(不是全部)C#的编译时安全性,以换取类似python的语法。
评论
var
我理解对 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对象,什么?我还是要浪费时间查一下......需要 IntelliSense 拐杖来挽救我懒惰编程的一天。也许在函数名称中包含返回类型。好主意,现在使用 var 除了使我的所有函数都具有真正的长名称之外,什么也没为我们节省任何东西。
我认为人们过度使用 var,这导致了懒惰的编程,这反过来又导致代码更难阅读。每次输入关键字 var 时,您都应该有充分的理由使用它,而不是明确。
评论
有时类型非常大。想象一下,在字典中有一个具有泛型类型的字典。var 将使它更具可读性。 它也是一种编码实践。
此外,如果您想创建匿名类型,例如 var randomData = { Id = 1, name = “Amit” }
我个人使用类型,因为有时你需要知道函数返回什么(以防万一,你想将结果传递给其他一些函数。查看类型比将光标悬停在 var 上更容易。 例如:var result = GetSomethign();
此外,有时您需要导航到按 F12 的类型。这在 var 中是不可能的。当您处于调试模式时,这有点烦人,因为在调试时看不到类型。您需要停止调试,查看类型并重新开始调试。
上一个:实例变量声明的放置
评论