何时应该使用 "var" 而不是 "object"?

4

我在想何时应该使用var

C#中几乎所有东西,除了一些基本类型和少数更奇怪的情况外,都派生自Object。

那么使用实际类型或至少使用object不是更好的做法吗?

(我已经编程有一段时间了,我的严格观点是var是邪恶的)


https://dev59.com/T3I_5IYBdhLWcg3wDOdC - Marty Neal
https://dev59.com/fk7Sa4cB1Zd3GeqP8fwP - Marty Neal
12
var不是“邪恶的”,var是“很棒的”。这三个字母可以让你在创建ObservableCollection<AGiantClassNameThatHasAGenericType<AnotherReallyLongName>>时仅需输入一次,避免了重复输入。 - John Gardner
https://dev59.com/HlLTa4cB1Zd3GeqPdcrb - Marty Neal
1
从旧的Visual Basic时代开始的var与.NET C# var根本不同。后者始终是强类型的。 - Andrew Lewis
6个回答

29
你误解了:var 不是一种类型。 var 指示编译器根据变量的初始化使用正确的类型。
例如:
var s = "hello";         // s is of type string
var i = 42;              // i is of type int
var x = new [] { 43.3 }; // x is of type double[]
var y = new Foo();       // y is of type Foo

使用var时,您的变量仍然是强类型的。因此,var不是“邪恶”的。相反,它非常方便,正如我在其他地方所说的那样,我广泛使用它。 C# 的主要开发人员之一 Eric Lippert 也曾经详细讨论var是否是不良实践的问题。简而言之,“不是”。


仅使用 var 是否是不好的编程习惯?为什么会选择使用 var 而不是显式类型转换? - Tom Gullen
3
@Tom,我们有多个关于这个问题的帖子。使用情况备受争议,但我并不是很理解问题所在。我几乎在任何地方都使用它,除非(非常少见!)可读性会因此受到影响。 - Konrad Rudolph
我知道,我的意思是“在声明变量类型时”,这不会被认为是不好的做法吗? - Yochai Timmer
3
@Yochai:那就这样写。在那种情境下,如果你具体说明类型,会更清晰。但当人们开始使用“不良做法”这个术语时,我会感到不安。因为它暗示着只有一种正确的方式来做事情,而很少有这样的情况。 - Robert Harvey
@Konrad Rudolph:如果你知道你在做什么,类型并不重要。脚本语言也可以很好地工作,而无需类型声明。但是使用类型名称的好处在于可维护性... 当然你知道你在做什么,但是两个月后另一个程序员看着代码还能理解它吗?在这种情况下,类型信息会说出很多问题的答案。 - Yochai Timmer
显示剩余5条评论

9
你把vardynamic混淆了,使用var与完全写出类型名称完全相同*,编译器将它们渲染为相同的代码。Eric Lippert的博客提供了关于var关键字的作用以及何时使用它的一些绝佳信息。
来自Eric Lippert文章Uses and misuses of implicit typing:

总之,我的建议是:

  • 在使用匿名类型时,必须使用var
  • 当声明的类型从初始化器中明显时,特别是在对象创建时,应使用var。这消除了冗余。
  • 如果代码强调变量的语义“业务目的”,并淡化其存储的“机械”细节,请考虑使用var
  • 如果必须正确理解和维护代码,则使用显式类型。
  • 无论是否使用“var”,都应使用描述性变量名称。变量名称应表示变量的语义,而不是其存储的详细信息;“decimalRate”是不好的;“interestRate”是好的。

*一些人可能会对我的“完全相同”的说法提出异议。对于匿名类型,这并不严格正确,但这是因为您不能合法地写出类型名称。


https://learn.microsoft.com/en-gb/archive/blogs/ericlippert/uses-and-misuses-of-implicit-typing - Arwin
@Arwin - 已更新链接。谢谢。 - Justin Morgan

5
使用object会丢失所有静态类型信息(并且在值类型上使用它甚至会导致装箱)。因此,使用object与使用var非常不同。
另一方面,var相当于使用实际(静态)类型。因此,当声明实际类型不可能或不方便时使用它。
其中需要使用var的一个场景是使用匿名类型。它们没有名称(挑刺:只有一个编译器生成的名称,你不知道),因此无法显式命名类型。
使用var方便的一种情况是当您的类型名称非常长时。这在使用嵌套泛型时有时会发生。
foreach循环中使用var可以避免不安全的隐式转换。

4
varobject是两个完全不同的东西。
使用var时,编译器会为您推断类型。而object是一个对象,由于C#是一种强类型语言,所以您将失去有关实例的任何信息。
请参阅C#规范第26.1节:
“在隐式类型的局部变量声明中,正在声明的局部变量的类型是从用于初始化变量的表达式中推断出来的。当局部变量声明将var指定为类型并且没有名为var的类型在作用域中时,则该声明是一个隐式类型的局部变量声明。”

2

你的“严格观点”有些误解...... var确实使用了实际的类型。编译器分析右侧表达式的返回类型,并将其作为赋值的类型。


我从未怀疑编译器,只是想知道这是否是一种良好的编程实践。 - Yochai Timmer
我认为只有在基本了解类型但输入太长时,这才是一种非常好的实践。(例如,在使用LINQ to Objects时真的很有帮助。) - Platinum Azure

1

var 不是一种类型。 var 告诉编译器:“我不确定/懒得在这里键入正确的类型名称,请根据语句上下文推断类型。”

Object 将对象转换为类型 Object。 结果您将失去任何类型信息,因此无法再调用在比 Object 更低层次中定义的特定方法、访问属性等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接