49

var关键字消除了对显式类型声明的需要,我感兴趣地阅读了关于何时可能合适的SO讨论

我还阅读了关于(但未使用过)Boo的内容,它似乎通过将声明局部变量设为可选而使事情更进了一步。使用 Boo,类型和声明都可以隐含。

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

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

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

相对

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

9 回答 9

48

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

name = "fred";
   ...
Name = "barney"; // whoops! we meant to reuse name
于 2008-10-16T16:04:35.973 回答
46

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

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

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

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

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

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

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

于 2008-10-16T16:12:16.660 回答
41

我理解对 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 时,都应该有充分的理由使用它而不是显式地使用它。

于 2009-04-29T22:27:09.173 回答
6

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

变量声明的位置很明显:

var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

声明变量的位置不明显:

myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

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

于 2008-10-16T16:06:34.660 回答
5

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

例如,在您问题的更新部分,您询问了以下代码段:

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

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

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

于 2008-10-16T16:54:36.390 回答
3

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

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

bill=5;
bi11=bill+5

票据的价值是多少?

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

DataOutputStream ds=new DataOutputStream();

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

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

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

DataOutput ds=new DataOutputStream();

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

于 2008-10-16T16:26:02.890 回答
0

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

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

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

var 对 Linq 非常有用。事实上,根据一位专家作者的说法,“如果没有 'var',LINQ 使用起来会很痛苦。

于 2008-10-16T16:01:07.293 回答
0

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

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

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

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

于 2020-11-19T13:38:53.947 回答
-1

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

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

于 2008-10-16T16:01:37.463 回答