10

可能重复:
C# 'var' 关键字与显式定义的变量

编辑:

对于那些还在看这个的人,我已经完全改变了我对 var 的看法。我认为这主要是由于我对这个话题的反应。我现在是一个狂热的“var”用户,我认为下面的支持者评论在几乎所有情况下都是绝对正确的。我认为我最喜欢 var 的一点是它确实减少了重复(符合 DRY),并使您的代码相当干净。它支持重构(当您需要更改某些东西的返回类型时,您需要处理的代码清理工作较少,而且不,不是每个人都有花哨的重构工具!),而且有趣的是,人们似乎并没有真正遇到问题预先不知道变量的具体类型(它很容易按需“发现”类型的功能,无论如何这通常是必需的,

所以这里是对“var”关键字的热烈掌声!!


这是一个相对简单的问题……实际上更像是一个民意调查。我是 C# 的忠实拥护者,自从 .NET 首次发布之前,我已经使用它超过 8 年了。我喜欢对语言所做的所有改进,包括 lambda 表达式、扩展方法、LINQ 和匿名类型。但是,我觉得 C# 3.0 中的一项功能被严重滥用了……'var' 关键字。

自 C# 3.0 发布以来,在博客、论坛,是的,甚至 Stackoverflow 上,我已经看到 var 替换了几乎所有已编写的变量!对我来说,这是对该功能的严重滥用,并且由于不清楚变量实际上是什么类型而导致非常任意的代码可能包含许多混淆错误。

'var' 只有一个真正有效的用法(至少在我看来)。你问这个有效的用途是什么?唯一有效的用途是当您无法知道类型时,以及唯一可能发生这种情况的情况:

访问匿名类型时

匿名类型没有编译时标识,因此 var 是唯一的选择。这是添加 var 以支持匿名类型的唯一原因。

那么……你的意见是什么?鉴于 var 在博客、论坛上的大量使用,由 ReSharper 等工具建议/强制执行,许多新兴开发人员会将其视为完全有效的东西。

  • 你认为 var 应该被大量使用吗?
  • 你认为 var 应该用于匿名类型以外的任何东西吗?
  • 是否可以在发布到博客的代码中使用以保持简洁……简洁?(我自己不确定这个答案……也许有免责声明)
  • 作为一个社区,我们应该鼓励更好地使用强类型变量来提高代码清晰度,还是让 C# 变得更加模糊和更少描述性?

我想知道社区的意见。我看到 var 使用了很多,但我不知道为什么,也许有一个很好的理由(即简洁/简洁。)

4

11 回答 11

24

我认为它应该用于在同一语句的其他地方明确指定类型的情况:

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

读起来很痛苦。这可以用以下内容代替,而不会失去清晰度:

var myHashMap = new Dictionary<string, List<int>>();
于 2009-05-23T21:54:23.950 回答
24

var是一个绝妙的想法,可以帮助实现良好编程的关键原则:DRY,即不要重复自己。

VeryComplicatedType x = new VeryComplicatedType();

是糟糕的编码,因为它重复VeryComplicatedType,并且效果都是负面的:更冗长和样板的代码,更少的可读性,对于代码的读者和编写者来说都是愚蠢的“制作”。因此,var与 Java 和以前的 C# 版本相比,我认为 C# 3 中的一个非常有用的增强功能。

当然,它可能会被轻微误用,通过使用类型不明确且不明显的表达式作为 RHS(例如,调用声明可能很远的方法)——这种误用可能会降低可读性(通过迫使读者寻找方法的声明或深入思考其他微妙表达式的类型)而不是增加它。但是,如果您坚持使用var避免重复,您将处于最佳状态,并且不会误用。

于 2009-05-23T22:16:28.320 回答
10

突击测验!

这是什么类型:

var Foo = new string[]{"abc","123","yoda"};

这个怎么样:

var Bar = {"abc","123","yoda"};

与类型的显式冗余规范相比,我大致不再需要确定它们是什么类型。作为一名程序员,让编译器找出对我来说显而易见的事情是没有问题的。你可能不同意。

干杯。

于 2009-05-23T22:02:45.150 回答
6

永不说永不。我很确定有很多问题人们已经阐述了他们的观点var,但这里又是我的问题。

var是工具;在合适的地方使用它,在不合适的时候不要使用它。您是对的,唯一需要使用的var是在处理匿名类型时,在这种情况下您没有要使用的类型名称。就个人而言,我认为任何其他用途都必须从可读性和惰性方面考虑;特别是在避免使用繁琐的类型名称时。

var i = 5;

(懒惰)

var list = new List<Customer>();

(方便)

var customers = GetCustomers();

(有问题;当且仅当 GetCustomers() 返回 IEnumerable 时,我才认为它可以接受)

于 2009-05-23T21:55:29.017 回答
4

阅读 Haskell。它是一种静态类型语言,您很少需要说明任何内容的类型。因此它使用与 var 相同的方法,作为标准的“惯用”编码风格。

如果编译器可以为您解决问题,为什么要写两次相同的东西?

我的一个同事一开始和你一样非常反对var,但现在已经开始习惯性地使用它。他担心这会减少程序的自我记录,但实际上这更多是由于方法过长造成的。

于 2009-05-23T21:56:42.417 回答
3
var MyCustomers = from c in Customers 
                  where c.City="Madrid" 
                  select new { c.Company, c.Mail };

如果我只需要客户收集的公司和邮件。用我需要的成员定义新类型是胡说八道。

于 2009-05-23T22:03:08.207 回答
1

如果您认为两次提供相同的信息可以减少错误(许多坚持您输入两次电子邮件地址的 Web 表单的设计者似乎也同意),那么您可能会讨厌 var。如果您编写了大量使用复杂类型规范的代码,那么这是天赐之物。

编辑:稍微扩展一下(以防听起来我不赞成 var):

在英国(至少在我去的时候),让计算机科学专业的学生学习如何使用标准 ML 编程是标准做法。与其他函数式语言一样,它有一个类型系统,使 C++/Java 模式中的语言相形见绌。

无论如何,我当时注意到(并听到其他学生的类似评论)是让你的 SML 程序编译是一场噩梦,因为编译器对类型非常挑剔,但一旦编译,它们几乎总是运行没有错误。

SML(和其他函数式语言)的这一方面似乎被提问者视为“好事”——即任何有助于编译器在编译时捕获更多错误的东西都是好的。

现在这是 SML 的问题:它在分配时专门使用类型推断。所以我不认为类型推断本质上是坏的。

于 2009-05-23T22:02:01.437 回答
1

我同意其他人的观点,即 var 消除了冗余。我决定使用 var 尽可能消除冗余。我认为一致性很重要。选择一种风格并通过项目坚持下去。

于 2009-05-23T22:07:03.113 回答
0

正如 Earwicker 所指出的,有一些函数式语言,Haskell 是一种,F# 是另一种,其中这种类型推断的使用更为普遍——C# 的类比是将方法的返回类型和参数类型声明为“var”,然后让编译器为您推断静态类型。静态类型和显式类型是两个正交的问题。

事实上,说使用“var”是动态类型是否正确?据我了解,这就是 C# 4.0 中新的“动态”关键字的用途。“var”用于静态类型推断。如果我错了,请纠正我。

于 2009-05-23T22:00:09.820 回答
0

我必须承认,当我第一次看到 var 关键字弹出时,我非常怀疑。

然而,这绝对是一种缩短新声明行数的简单方法,我一直为此使用它。

但是,当我更改底层方法的类型并使用 var 接受返回类型时。我确实偶尔会遇到运行时错误。大多数仍然由编译器拾取。

我遇到的第二个问题是当我不确定使用什么方法时(我只是在查看自动完成)。如果我选择了错误的类型并期望它是 FOO 类型并且它是 BAR 类型,那么需要一段时间才能弄清楚。

如果我在这两种情况下都按字面意思指定了变量类型,那将节省一些挫败感。

总体而言,收益大于问题。

于 2009-05-23T22:21:55.580 回答
0

我不得不反对 var 以任何有意义的方式减少冗余的观点。在此处提出的情况下,类型推断可以而且应该来自 IDE,它可以在不损失可读性的情况下更自由地应用。

于 2009-05-24T00:06:20.143 回答