已锁定 。 该问题及其答案被
锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。
与同事讨论了在C#3中使用'var'关键字后,我想知道人们对于通过var进行类型推断的适当用法有何看法?
例如,我宁愿在可疑的情况下懒惰地使用var,例如:
foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.
var的更多合法用法如下:
var l = new List(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.
有趣的是,LINQ似乎有点灰色,例如:
var results = from r in dataContext.SomeTable
select r; // Not *entirely clear* what results will be here.
很明显,它将产生一个实现IEnumerable的类型,但结果并不完全相同,就像声明一个新对象的var一样。
当涉及对象的LINQ时,甚至更糟,例如:
var results = from item in someList
where item != 3
select item;
这并不比等价的foreach(someList中的var item){// ...}等值好。
这里确实有关于类型安全的问题-例如,如果我们将查询的结果放入接受了IEnumerable 和IEnumerable 的重载方法中,则调用者可能会无意中传递错误的类型。
var 确实保持强类型,但是问题实际上是类型在定义时不立即变得危险吗?当重载意味着当您无意将错误类型传递给方法时,可能不会发出编译器错误时,这种情况会放大。
#1楼
对我来说,对var的反感说明了.NET中双语的重要性。 对于也完成了VB .NET的C#程序员而言, var的优势在直观上显而易见。 标准的C#声明:
List whatever = new List();
在VB .NET中相当于键入以下内容:
Dim whatever As List(Of String) = New List(Of String)
但是,没有人在VB .NET中这样做。 这样做很愚蠢,因为自从.NET的第一个版本以来,您已经能够做到这一点...
Dim whatever As New List(Of String)
...这会创建变量并将其全部初始化为紧凑的一行。 啊,但是如果要IList而不是List怎么办? 好吧,在VB .NET中,这意味着您必须执行以下操作:
Dim whatever As IList(Of String) = New List(Of String)
就像您必须使用C#一样,并且显然不能将var用于:
IList whatever = new List();
如果您需要类型有所不同,可以。 但是,良好编程的基本原理之一是减少冗余,而这正是var所做的。
#2楼
#3楼
您最可能需要的时间是匿名类型(要求100%); 但这也避免了琐碎的重复,国际海事组织使这一界限更加清晰。 我不需要两次查看类型即可进行简单的初始化。
例如:
Dictionary>> data = new Dictionary>>();
(请不要在上面编辑hscroll-有点证明了这一点!!!)
vs:
var data = new Dictionary>>();
但是,在某些情况下,这会产生误导,并可能导致错误。 如果原始变量和初始化类型不同,请小心使用var 。 例如:
static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}
// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);
#4楼
使用var而不是显式类型使重构更加容易(因此,我必须与之前的声明相矛盾,后者意味着它没有什么作用,或者纯粹是“语法糖”)。
您可以更改方法的返回类型,而无需更改调用此方法的每个文件。 想像
...
List SomeMethod() { ... }
...
像
...
IList list = obj.SomeMethod();
foreach (MyClass c in list)
System.Console.WriteLine(c.ToString());
...
如果要重构SomeMethod()以返回IEnumerable ,则必须在使用该方法的每个位置更改变量声明(也在foreach )。
如果你写
...
var list = obj.SomeMethod();
foreach (var element in list)
System.Console.WriteLine(element.ToString());
...
相反,您不必更改它。
#5楼
将其用于匿名类型-这就是它的用途。 其他任何用途都太远了。 像许多在C上长大的人一样,我习惯于在类型声明的左侧。 除非必须,否则我不会在右边看。 对任何旧声明使用var会使我一直这样做,我个人感到不舒服。
那些说“没关系,用自己满意的东西”的人并没有看到全部。 每个人都会在某一点或另一点拾取别人的代码,并且必须处理他们在编写代码时所做的任何决定。 必须处理根本不同的命名约定,或者-经典的抱怨-支撑样式,而又不添加整个“ var or not”的东西,这已经够糟糕了。 最糟糕的情况是,一个程序员没有使用var ,然后出现了一个热爱它的维护者,并使用它来扩展代码。 所以现在你有一个邪恶的混乱。
标准恰好是一件好事,因为它们意味着您更有可能拾取随机代码并能够快速使用它。 不同的事物越多,获得的难度就越大。 转变为“无处不在”的风格带来了很大的不同。
我不介意动态打字,也不介意隐式打字-使用为他们设计的语言。 我很喜欢Python。 但是C#被设计为静态显式类型的语言,因此它应该保持不变。 打破匿名类型的规则已经很糟糕了。 我不满意让别人更进一步,打破语言的习语。 既然精灵已经从瓶子里拿出来了,就永远不会再回来了。C#会陷入困境。 不好。