405

在与同事讨论了 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<string>(); // 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(var item in someList) { // ... } 等价。

这里有一个关于类型安全的真正担忧——例如,如果我们将该查询的结果放入一个接受 IEnumerable<int> 和 IEnumerable<double> 的重载方法中,调用者可能会无意中传入错误的类型。

var 确实保持强类型,但问题是类型在定义时不立即显现是否很危险,当重载时会放大的东西意味着当您无意中将错误的类型传递给方法时可能不会发出编译器错误。

4

86 回答 86

292

我仍然认为var在某些情况下可以使代码更具可读性。如果我有一个带有 Orders 属性的 Customer 类,并且我想将它分配给一个变量,我将这样做:

var orders = cust.Orders;

我不在乎 Customer.Orders 是IEnumerable<Order>,ObservableCollection<Order>还是BindingList<Order>- 我想要的只是将该列表保存在内存中以对其进行迭代或稍后获取其计数或其他内容。

将上述声明与:

ObservableCollection<Order> orders = cust.Orders;

对我来说,类型名称只是噪音。如果我返回并决定更改 Customer.Orders 的类型(比如 from ObservableCollection<Order>to IList<Order>),那么我也需要更改该声明 - 如果我在第一次使用 var 时不必这样做地方。

于 2008-09-03T11:53:07.377 回答
167

var广泛使用。有人批评这会降低代码的可读性,但没有论据支持这种说法。

诚然,这可能意味着不清楚我们正在处理什么类型。所以呢?这实际上是解耦设计的重点。在处理接口时,您对变量的类型并不感兴趣。var确实如此,但我认为从可读性的角度来看,该论点保持不变:程序员实际上不应该对变量的类型感兴趣,而应该对变量的作用感兴趣。这就是为什么微软也将类型推断称为“鸭子类型”。</p>

那么,当我使用声明变量时,它会做什么var?很简单,它会执行 IntelliSense 告诉我的任何操作。任何忽略 IDE 的 C# 推理都不符合实际。实际上,每个 C# 代码都在支持 IntelliSense 的 IDE 中进行编程。

如果我正在使用已var声明的变量并且对变量的用途感到困惑,那么我的代码就存在根本性的问题。var不是原因,它只是使症状可见。不要责怪使者。

现在,C# 团队发布了一个编码指南,说明它只能var用于捕获创建匿名类型的 LINQ 语句的结果(因为在这里,我们没有真正的替代方案)。好吧,去他妈的。只要 C# 团队没有为该指南提供合理的论据,我就会忽略它,因为在我的专业和个人看来,这纯粹是胡扯。(抱歉;我没有相关指南的链接。)var

实际上,有一些(表面上)很好的解释为什么你不应该使用var,但我仍然认为它们在很大程度上是错误的。以“searchabililty”为例:作者声称这var使得搜索使用的地方变得困难MyType。对。接口也是如此。实际上,我为什么想知道该类在哪里使用?我可能对它在哪里实例化更感兴趣,并且这仍然是可搜索的,因为必须在某个地方调用它的构造函数(即使这是间接完成的,也必须在某处提及类型名称)。

于 2008-09-03T12:01:01.087 回答
118

Var,在我看来,在 C# 中是一件好事tm。任何如此类型化的变量仍然是强类型的,但它从定义它的赋值的右侧获取其类型。因为类型信息在右侧可用,所以在大多数情况下,还必须在左侧输入它是不必要且过于冗长的。我认为这在不降低类型安全性的情况下显着提高了可读性。

从我的角度来看,从可读性的角度来看,对变量和方法使用良好的命名约定比显式类型信息更重要。如果我需要类型信息,我总是可以将鼠标悬停在变量上(在 VS 中)并获取它。不过,一般来说,读者不需要明确的类型信息。对于开发人员,在 VS 中,您仍然可以获得 Intellisense,无论变量是如何声明的。说了这么多,可能仍然存在显式声明类型确实有意义的情况——也许你有一个返回 a 的方法List<T>,但你想把它当作一个IEnumerable<T>在你的方法中。为确保您正在使用接口,声明接口类型的变量可以使其显式。或者,也许,您想声明一个没有初始值的变量——因为它会根据某些条件立即获得一个值。在这种情况下,您需要类型。如果类型信息有用或必要,请继续使用它。不过,我觉得通常没有必要,而且在大多数情况下,如果没有它,代码更容易阅读。

于 2010-05-19T13:50:50.237 回答
91

这些都不是绝对正确的。var对可读性有正面和负面的影响。在我看来,var应在以下任一情况下使用:

  1. 类型是匿名的(好吧,你在这里没有任何选择,因为在这种情况下它必须是 var )
  2. 根据分配的表达式(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating()) ,类型很明显

var没有性能影响,因为它是语法糖;编译器会推断类型并在编译成 IL 后对其进行定义;实际上没有什么动态的。

于 2010-05-19T13:49:26.243 回答
68

来自 C# 团队的高级软件设计工程师 Eric Lippert:

为什么要var引入关键字?

有两个原因,一个现在存在,一个将在 3.0 中出现。

第一个原因是由于所有冗余,这段代码非常难看:

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

这是一个简单的例子——我写得更糟。每当您被迫两次键入完全相同的内容时,我们就可以消除这种冗余。写的好很多

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

并让编译器根据赋值确定类型是什么。

其次,C# 3.0 引入了匿名类型。由于定义的匿名类型没有名称,因此如果变量的类型是匿名的,则需要能够从初始化表达式中推断出变量的类型。

强调我的。整篇文章,C# 3.0 还是静态类型的,老实说!,接下来的系列都还不错。

这是var为了什么。其他用途可能不会那么好。任何与 JScript、VBScript 或动态类型的比较都是完全错误的。再次注意,为了使某些其他功能在 .NET 中工作,var它是必需的。

于 2008-09-18T20:22:53.030 回答
53

我认为 var 的使用应该与明智选择的变量名相结合。

我在 foreach 语句中使用 var 没有问题,只要它不是这样的:

foreach (var c in list) { ... }

如果它更像这样:

foreach (var customer in list) { ... }

...那么阅读代码的人将更有可能理解“列表”是什么。如果您可以控制列表变量本身的名称,那就更好了。

这同样适用于其他情况。这是非常没用的:

var x = SaveFoo(foo);

...但这是有道理的:

var saveSucceeded = SaveFoo(foo);

每个人都有他自己的,我猜。我发现自己这样做了,这太疯狂了:

var f = (float)3;

我需要某种 12 步 var 程序。我的名字是马特,我(ab)使用 var。

于 2008-09-03T11:35:13.987 回答
40

我们采用了“为人而非机器编写代码”的理念,假设您在维护模式下花费的时间是新开发的数倍。

对我来说,这排除了编译器“知道”变量是什么类型的论点——当然,你不能在第一次编写无效代码,因为编译器会阻止你的代码编译,但是当下一个开发人员正在阅读代码时在 6 个月的时间内,他们需要能够推断出变量的正确或错误行为,并快速确定问题的原因。

因此,

var something = SomeMethod();

被我们的编码标准禁止,但我们的团队鼓励以下内容,因为它增加了可读性:

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item ); 
}
于 2008-09-17T01:08:18.007 回答
39

这还不错,它更像是一种风格上的东西,这往往是主观的。当您使用 var 和不使用时,它会增加不一致。

另一个值得关注的情况是,在以下调用中,您无法仅通过查看返回的类型的代码来判断CallMe

var variable = CallMe();

这是我对 var 的主要抱怨。

我在方法中声明匿名委托时使用 var ,不知何故 var 看起来比我使用Func. 考虑这段代码:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

编辑:根据 Julian 的输入更新了最后一个代码示例

于 2010-05-19T13:48:33.517 回答
36

Var 根本不像变体。该变量仍然是强类型的,只是您不需要按键来获得它。您可以在 Visual Studio 中将鼠标悬停在其上以查看类型。如果您正在阅读打印的代码,您可能需要稍微思考一下才能弄清楚类型是什么。但是只有一行声明了它,并且有很多行使用了它,所以给东西起个好听的名字仍然是让你的代码更容易理解的最好方法。

使用 Intellisense 是不是很懒惰?它的打字比全名少。还是有一些工作较少但不值得批评的事情?我认为有,而 var 就是其中之一。

于 2010-05-19T13:47:43.610 回答
27

您最可能需要的时间是匿名类型(100% 需要);但它也避免了琐碎案例的重复,IMO使这条线更清晰。我不需要两次查看类型即可进行简单的初始化。

例如:

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

(请不要编辑上面的 hscroll - 这有点证明了这一点!!!)

与:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

但是,有时这会产生误导,并可能导致错误。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);
于 2009-08-19T07:17:12.507 回答
17

var 困难的一种特殊情况:离线代码审查,尤其是在纸上完成的代码审查。

你不能依赖鼠标悬停。

于 2008-09-03T11:51:16.537 回答
17

我看不出有什么大不了的。。

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

您仍然对“某事”具有完整的智能感知,并且对于任何模棱两可的情况,您都有单元测试,对吗?( 你? )

它不是 varchar,也不是 dim,当然也不是动态或弱类型。它正在阻止这样的疯狂:

List<somethinglongtypename> v = new List<somethinglongtypename>();

并将整个头脑混乱减少到:

var v = new List<somethinglongtypename>();

不错,不如:

v = List<somethinglongtypename>();

但这就是Boo的用途。

于 2008-09-03T12:04:57.923 回答
17

如果有人var因为不想“弄清楚类型”而使用关键字,那绝对是错误的原因。var关键字不会创建具有动态类型的变量,编译器仍然必须知道类型。由于变量始终具有特定类型,因此如果可能,该类型也应该在代码中显而易见。

使用关键字的充分理由var例如:

  • 在需要的地方,即声明一个匿名类型的引用。
  • 它使代码更具可读性,即删除重复声明。

写出数据类型通常会使代码更容易理解。它显示了您正在使用的数据类型,因此您不必先弄清楚代码的作用来确定数据类型。

于 2010-05-19T13:51:38.680 回答
11

鉴于 Intellisense 现在的强大功能,我不确定 var 是否比在类中具有成员变量或在可见屏幕区域外定义的方法中具有局部变量更难阅读。

如果您有一行代码,例如

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Is 比以下内容更容易或更难阅读:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();
于 2009-06-09T19:10:37.817 回答
10

我认为 VAR 的关键是仅在适当的情况下使用它,即在 Linq 中执行它促进的事情时(可能在其他情况下)。

如果你一个类型,那么你应该使用它 - 不这样做是简单的懒惰(与通常鼓励的创造性懒惰相反 - 优秀的程序员通常非常努力地变得懒惰并且可以考虑首先是事物的来源)。

全面禁止与滥用该结构一样糟糕,但确实需要一个合理的编码标准。

要记住的另一件事是,它不是 VB 类型的 var,因为它不能更改类型 - 它一个强类型变量,只是类型是推断出来的(这就是为什么有人会争辩说它不是不合理的例如,在 foreach 中使用它,但出于可读性和可维护性的原因,我不同意)。

我怀疑这个会运行和运行(-:

墨菲

于 2008-09-03T11:47:35.453 回答
10

当然,int这很容易,但是当变量的类型是IEnumerable<MyStupidLongNamedGenericClass<int, string>>var 时,事情会变得更容易。

于 2010-05-19T13:54:09.203 回答
9

CodingHorror 上关于此问题的帖子中窃取


不幸的是,你和其他人几乎都搞错了。虽然我同意你的观点,冗余不是一件好事,但解决这个问题的更好方法是执行以下操作:

我的对象 m = new();

或者,如果您要传递参数:

人 p = new("FirstName", "LastName);

在创建新对象时,编译器从左侧推断类型,而不是右侧。与“var”相比,它还有其他优点,因为它也可以用于字段声明(还有一些其他领域也可能有用,但我不会在这里讨论)。

最后,它并不是为了减少冗余。不要误会我的意思,“var”在 C# 中对于匿名类型/投影非常重要,但这里的使用只是路途遥远(我已经说了很长时间了)因为你混淆了正在使用。必须键入两次太频繁了,但将其声明为零次太少了。

Nicholas Paldino .NET/C# MVP 于 2008 年 6 月 20 日 08:00 AM


我想如果你主要关心的是必须少打字——那么没有任何论据会影响你使用它。

如果您只想成为查看代码的人,那么谁在乎呢否则,在这种情况下:

var people = Managers.People

没关系,但在这种情况下:

var fc = Factory.Run();

它缩短了我的大脑可以从代码的“英语”开始形成的任何直接类型推断。

否则,只需对可能需要为您的项目工作的其他人使用您的最佳判断和编程“礼貌”。

于 2008-12-24T14:51:13.420 回答
9

使用var而不是显式类型使重构更容易(因此我必须与之前的海报相矛盾,他们的意思是它没有任何区别,或者它纯粹是“语法糖”)。

您可以更改方法的返回类型,而无需更改调用此方法的每个文件。想象

...
List<MyClass> SomeMethod() { ... }
...

像这样使用

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

如果要重构SomeMethod()以返回,则必须在使用该方法的每个位置IEnumerable<MySecondClass>更改变量声明(也在 内部)。foreach

如果你写

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

相反,您不必更改它。

于 2009-08-19T07:21:36.290 回答
8

@aku:一个例子是代码审查。另一个例子是重构场景。

基本上我不想用我的鼠标进行类型搜索。它可能不可用。

于 2008-09-03T12:02:03.080 回答
8

这是一个品味问题。当您习惯了动态类型语言时,所有这些关于变量类型的大惊小怪都消失了。也就是说,如果您开始喜欢它们(我不确定是否每个人都可以,但我可以)。

C#var非常酷,因为它看起来像动态类型,但实际上是静态类型 - 编译器强制正确使用。

您的变量的类型并不是那么重要(之前已经说过)。从上下文(它与其他变量和方法的交互)及其名称中应该相对清楚 - 不要期望customerList包含int...

我还在等着看我的老板对这件事的看法——我得到了一张毯子“继续”使用 3.5 中的任何新构造,但我们将如何维护?

于 2008-09-03T12:10:53.463 回答
7

在你比较IEnumerable<int>IEnumerable<double>你不需要担心 - 如果你传递错误的类型,你的代码无论如何都不会编译。

无需担心类型安全,因为var不是动态的。这只是编译器的魔法,您进行的任何类型的不安全调用都会被捕获。

VarLinq 绝对需要:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

现在看一下智能感知中的anonEnumeration,它会出现类似IEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

C# 编译器非常聪明——如果它们的属性匹配,单独生成的匿名类型将具有相同的生成类型。

除此之外,只要你有智能感知,在var任何上下文清晰的地方使用都是很有意义的。

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;
于 2008-09-03T12:13:33.020 回答
7

我想这取决于你的观点。我个人从来没有因为var“误用”而在理解一段代码时遇到任何困难,我和我的同事都经常使用它。(我同意 Intellisense 在这方面是一个巨大的帮助。)我欢迎它作为一种消除重复性的方式。

毕竟,如果语句像

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

真的那么不可能处理,没有人会使用动态类型的语言。

于 2009-06-09T19:08:54.967 回答
7

我只在清楚地看到使用什么类型时才使用 var 。

例如,在这种情况下我会使用 var,因为您可以立即看到 x 的类型为“MyClass”:

var x = new MyClass();

在这种情况下我不会使用 var ,因为您必须将鼠标拖到代码上并查看工具提示以查看 MyFunction 返回的类型:

var x = MyClass.MyFunction();

特别是,在右侧甚至不是方法,而只是一个值的情况下,我从不使用 var:

var x = 5;

(因为编译器不知道我是否想要一个字节,短,整数或其他)

于 2010-05-19T14:09:30.927 回答
6

对我来说,对 .NET 中双语的反感var说明了为什么双语很重要。对于那些也做过VB .NET的C#程序员来说,其优势var是显而易见的。标准 C# 声明:

List<string> whatever = new List<string>();

在 VB .NET 中,相当于键入以下内容:

Dim whatever As List(Of String) = New List(Of String)

但是,在 VB .NET 中没有人这样做。这将是愚蠢的,因为自从 .NET 的第一个版本以来,您已经能够做到这一点......

Dim whatever As New List(Of String)

...创建变量并将其全部初始化在一个相当紧凑的行中。啊,但是如果你想要一个IList<string>,而不是一个List<string>呢?好吧,在 VB .NET 中,这意味着您必须这样做:

Dim whatever As IList(Of String) = New List(Of String)

就像你必须在 C# 中做的那样,显然不能var用于:

IList<string> whatever = new List<string>();

如果你需要不同的类型,它可以。但是良好编程的基本原则之一是减少冗余,而这正是 var 所做的。

于 2008-09-19T20:45:41.443 回答
6

将它用于匿名类型 - 这就是它的用途。其他任何东西都用得太远了。像许多在 C 上长大的人一样,我习惯于查看类型声明的左侧。除非必须,否则我不会看右侧。使用var任何旧的声明让我一直这样做,我个人觉得这很不舒服。

那些说“没关系,用你喜欢的东西”的人并没有看到全貌。每个人都会在某一时刻拿起其他人的代码,并且必须处理他们在编写代码时做出的任何决定。不得不处理完全不同的命名约定,或者 - 经典的抱怨 - 支撑样式,而没有将整个“var或不”添加到组合中,这已经够糟糕的了。最坏的情况是一个程序员不使用var它,然后一个喜欢它的维护者出现,并使用它扩展代码。所以现在你有一个邪恶的混乱。

标准是一件好事,正是因为它们意味着您更有可能获取随机代码并能够快速理解它。不同的东西越多,就越难。转向“无处不在的var”风格会产生很大的不同。

我不介意动态输入,也不介意隐式输入——使用为他们设计的语言。我非常喜欢 Python。但是 C# 被设计为一种静态显式类型的语言,这就是它应该保持的方式。打破匿名类型的规则已经够糟糕的了;让人们更进一步并打破语言的习语是我不满意的事情。既然精灵已经从瓶子里拿出来了,它就永远不会再回来了。C# 将被分道扬镳。不好。

于 2008-09-25T14:34:59.677 回答
6

在测试过程中很多时候,我发现自己有这样的代码:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

现在,有时,我想看看 SomeOtherThing 本身包含什么, SomeOtherThing 与 CallMethod() 返回的类型不同。由于我使用的是 var ,所以我只是更改了这个:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

对此:

var something = myObject.SomeProperty.SomeOtherThing;

如果没有 var,我也必须不断更改左侧声明的类型。我知道这是次要的,但它非常方便。

于 2009-06-09T19:15:54.280 回答
6

对于认为var节省时间的爱好者来说,键入所需的击键次数更少:

StringBuilder sb = new StringBuilder();

var sb = new StringBuilder();

如果你不相信我,数数他们...

19 对 21

如果必须,我会解释,但只是尝试一下......(取决于你的智能感知的当前状态,你可能需要为每个输入更多)

你能想到的每一种类型都是如此!

我个人的感觉是,除非类型未知,否则永远不应该使用 var,因为它会降低代码中的识别可读性。大脑识别类型比识别整行需要更长的时间。了解机器代码和位的老手都知道我在说什么。大脑并行处理,当您使用 var 时,您会强制它序列化其输入。为什么有人想让他们的大脑更努力地工作?这就是计算机的用途。

于 2010-03-11T18:27:24.287 回答
5

我在所有地方拆分 var,对我来说唯一有问题的地方是内部短类型,例如我更int i = 3;喜欢var i = 3;

于 2008-09-03T12:13:43.380 回答
5

从我昨天写的代码来看,它当然可以让事情变得更简单:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

如果没有var.

附录:花一点时间使用具有真实类型推断的语言(例如 F#)将显示编译器在正确获取表达式类型方面的出色表现。这当然意味着我倾向于var尽可能多地使用,并且现在使用显式类型表明该变量不是初始化表达式的类型。

于 2009-06-09T19:12:18.890 回答
5

没有,除了你不必写两次类型名称。http://msdn.microsoft.com/en-us/library/bb383973.aspx

于 2009-08-19T07:09:08.640 回答
5

在大多数情况下,键入它更简单 - 想象一下

var sb = new StringBuilder();

代替:

StringBuilder sb = new StringBuilder();

有时它是必需的,例如:匿名类型,例如。

var stuff = new { Name = "Me", Age = 20 };

我个人喜欢使用它,尽管它会降低代码的可读性和可维护性。

于 2009-08-19T07:09:32.150 回答
5

我曾经认为 var 关键字是一项伟大的发明,但我对其进行了限制,这是

  • 仅在类型很明显时才使用 var (不滚动或查看返回类型)

我开始意识到这一点并没有给我带来任何好处,并从我的代码中删除了所有 var 关键字(除非特别需要它们),现在我认为它们使代码的可读性降低,尤其是对于其他阅读您的代码的人。

它隐藏了意图,并且至少在一种情况下由于类型的假设而导致某些代码中出现运行时错误。

于 2009-09-02T13:20:38.947 回答
4

使用 LINQ 的另一个很好的理由var是编译器可以进一步优化查询。

如果您使用静态列表来存储结果,它将在您将其分配给列表的位置执行,但var它可以潜在地将原始查询与代码中的后续查询合并,以对数据库进行更优化的查询。

我有一个示例,我在第一个查询中提取了一些数据,然后循环并请求更多数据以打印出一个表。

LINQ 合并这些,以便第一个只提取 id。

然后在循环中,它添加了一个我没有在那里完成的额外连接来获取我包含在原始文件中的数据。

经过测试,这证明效率更高。

如果我们没有使用var它,它会完全按照我们编写的方式进行查询。

于 2010-10-25T10:01:27.963 回答
3

当我开始使用var关键字时,我也有同样的担忧。
但是,随着时间的推移,我已经习惯了它,并且不会再回到显式变量类型。Visual Studio 的编译器\intellisense 在简化隐式类型变量的工作方面做得非常好。

我认为遵循正确的命名约定可以帮助您比显式键入更好地理解代码。

这似乎是类似“我应该在变量名中使用前缀吗?”之类的问题。
坚持使用好的变量名,让编译器考虑变量类型。

于 2008-09-03T11:36:00.927 回答
3

有人不喜欢批评 var.. 所有答案都被下调了.. 哦,好吧..

@Jon Limjap:我知道。:) 我的意思是可读性下降,就像在 VB6 中一样。我不喜欢依靠 Intellisense 来确定给定变量的类型。我希望能够单独使用源来解决它。

命名约定也无济于事——我已经使用了好名字。我们要回到前缀吗?

于 2008-09-03T11:45:04.040 回答
3

var尽可能使用。

如果你的代码写得好(即,好的变量名、注释、清晰的结构等),局部变量的实际类型并不重要。

于 2009-01-28T16:55:12.300 回答
3

这纯粹是为了方便。编译器将推断类型(基于右侧表达式的类型)

于 2009-08-19T07:09:27.827 回答
3

从关于这个话题的讨论来看,结果似乎是:

好的:var customers = new List<Customer>();

有争议的:var customers = dataAccess.GetCustomers();

忽略“var”神奇地有助于重构的错误观点,对我来说最大的问题是人们坚持认为他们不关心返回类型是什么,“只要他们可以枚举集合”。

考虑:

IList<Customer> customers = dataAccess.GetCustomers();

var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

现在考虑:

var customers = dataAccess.GetCustomers();

var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

现在,去重构数据访问类,让 GetCustomers 返回IEnumerable<Customer>,看看会发生什么......

这里的问题是,在第一个示例中,您对 GetCustomers 方法的期望是明确的——您是说您希望它返回一些行为类似于列表的东西。在第二个示例中,这种期望是隐含的,并且从代码中不会立即显而易见。

有趣的是(对我来说)很多 pro-var 参数说“我不在乎它返回什么类型”,但继续说“我只需要迭代它......”。(所以它需要实现 IEnumerable 接口,这意味着类型确实很重要)。

于 2009-11-12T17:44:55.103 回答
3

好吧,这一点在整个过程中几乎都是固执己见的,但我会尝试发表我的观点——尽管我认为我的观点如此混乱,你可能无论如何也不会从中得到太多。

首先 - 有匿名类型,您需要使用“var”关键字来分配具有匿名类型的对象作为其类 - 这里没有太多讨论,需要“var”。

然而,对于更简单的类型,整数、长整数、字符串等等——我倾向于放入正确的类型。主要是因为它有点像“懒人的工具”,而且我在这里看不到多少收获,很少的击键和它在以后可能提供的混乱是不值得的。尤其是浮点数的各种类型(float、double、decimal)让我感到困惑,因为我对文字中的后缀并不坚定——我喜欢在源代码中查看类型。

话虽如此,如果类型更复杂和/或在赋值的右侧显式重复,我倾向于使用 var alot。这可能是一个List<string>或等,例如:

var list = new List<string>();

在这种情况下,我认为重复该类型两次是没有用的——尤其是当您开始更改代码并且类型发生更改时——泛型类型可能会变得越来越复杂,因此必须更改它们两次只是一种痛苦。但是,当然,如果您希望针对 an 进行编码,IList<string>则必须明确命名该类型。

所以简而言之,我执行以下操作:

  • 当类型很短或无法脱离上下文读取时,显式命名类型
  • 必须使用时使用 var (duh)
  • 当它(在我看来)不损害可读性时,使用 var 变得懒惰
于 2010-05-19T13:53:10.483 回答
3

在作为 Java 专业人士十年之后,我在 C# 世界中还算新人。我最初的想法是“哦,不!类型安全性已付诸东流”。然而,我对 var 的了解越多,我就越喜欢它。

1) Var 与显式声明的类型一样是类型安全的。这都是关于编译时语法糖的。

2)它遵循DRY原则(不要重复自己)。DRY 就是为了避免冗余,在两边命名类型肯定是多余的。避免冗余就是让您的代码更容易更改。

3)至于知道确切的类型..好吧..我认为你总是有一个一般的想法是你有一个整数、一个套接字、一些 UI 控件或其他什么。Intellisense 将从这里引导您。知道确切的类型通常并不重要。例如,我认为 99% 的时间你都不关心给定变量是 long 还是 int、float 还是 double。对于最后 1% 的情况,真正重要的是,只需将鼠标指针悬停在 var 关键字上方即可。

4)我看到了一个荒谬的论点,即现在我们需要回到 1980 年风格的匈牙利疣来区分变量类型。毕竟,在蒂莫西·道尔顿(Timothy Dalton)扮演詹姆斯·邦德(James Bond)的时代,这是分辨变量类型的唯一方法。但这是 2010 年。我们已经学会根据变量的用途和内容来命名变量,并让 IDE 指导我们了解它们的类型。只要继续这样做, var 就不会伤害你。

总结一下,var 不是什么大事,但确实是个好东西,是 Java 快要复制的一个东西。所有反对的论点似乎都是基于 IDE 之前的谬误。我会毫不犹豫地使用它,我很高兴 R# 帮助我这样做。

于 2010-10-26T06:00:34.243 回答
3

var 就像孩子们必须填写的儿童书籍中的虚线空间。除非在这种情况下,编译器会用正确的类型填充它,通常写在 = 符号之后。

于 2011-11-23T03:04:12.693 回答
2

在刚刚转换到 3.0 和 3.5 框架之后,我了解了这个关键字并决定试一试。在提交任何代码之前,我意识到它似乎是倒退的,就像回到 ASP 语法一样。所以我决定戳上级,看看他们是怎么想的。

他们说继续,所以我用它。

话虽如此,我避免在类型需要一些调查的地方使用它,如下所示:

var a = company.GetRecords();

现在它可能只是个人的事情,但我无法立即查看它并确定它是 Record 对象的集合还是表示记录名称的字符串数组。无论哪种情况,我认为显式声明在这种情况下都是有用的。

于 2008-09-03T13:46:04.843 回答
2

静态类型是关于合约,而不是源代码。这个想法需要在“应该”是一个小方法的单行上拥有静态信息。通用指南建议每个方法很少超过 25 行。

如果一个方法足够大,以至于您无法跟踪该方法中的单个变量,那么您正在做其他错误的事情,相比之下,对 var 的任何批评都显得苍白。

实际上,var 的一个重要论点是它可以使重构更简单,因为您不再需要担心您的声明过于严格(即,当您应该使用 IList<> 或 IEnumerable<> 时,您使用了 List<> )。您仍然想考虑新的方法签名,但至少您不必返回并更改您的声明以匹配。

于 2008-09-11T01:31:02.433 回答
2

在边缘情况附近肯定会有分歧,但我可以告诉你我的个人指导方针。

当我决定使用这些标准时,我会查看这些标准var

  • 从上下文来看,变量的类型是显而易见的
  • 变量的确切类型不是特别相关[与人类]
    [例如,您可以弄清楚算法在做什么,而无需关心您使用的是哪种容器]
  • 类型名很长,打断了代码的可读性(提示:通常是泛型的

相反,这些情况会促使我不使用var

  • 类型名称相对较短且易于阅读(提示:通常不是泛型
  • 从初始化器的名称看类型并不明显
  • 确切的类型对于理解代码/算法非常重要
  • 在类层次结构上,当人类无法轻易判断正在使用的层次结构级别时

最后,我永远不会使用var原生值类型或相应的nullable<>类型(int, decimal, string, decimal?, ...)。有一个隐含的假设,即如果您使用var,则必须有“原因”。

这些都是指导方针。您还应该考虑同事的经验和技能、算法的复杂性、变量的寿命/范围等。

大多数时候,没有完美的正确答案。或者,这并不重要。

[编辑:删除重复的项目符号]

于 2009-06-09T19:33:54.167 回答
2

很惊讶到目前为止还没有注意到这一点,但使用varforforeach循环变量是常识。

如果您改为指定特定类型,则可能会有运行时强制转换被编译器静默插入到您的程序中!

foreach (Derived d in listOfBase)
{

以上将编译。但是编译器会插入一个向下转换 from Baseto Derived。因此,如果列表中的任何内容Derived在运行时都不是 a,则存在无效的强制转换异常。类型安全受到损害。隐形演员是可怕的。

排除这种情况的唯一方法是使用var,因此编译器从列表的静态类型中确定循环变量的类型。

于 2010-04-30T17:22:51.267 回答
2

我想你可能误解了 C# 中 var 的用法。它仍然强类型,与 VB 变体类型不同,因此无论是否使用它都不会影响性能。

由于对最终编译的代码没有影响,因此它确实是造型师的选择。就我个人而言,我不使用它,因为我发现定义完整类型的代码更易于阅读,但我可以想象几年后完整类型声明将以与匈牙利表示法相同的方式看待 -与智能感知默认为我们提供的信息相比,额外的输入并没有真正的好处。

于 2010-05-19T13:50:00.423 回答
2

我认为您在问题中指出了 var 的主要问题:“我不必弄清楚类型”。正如其他人指出的那样,有一个 var 的地方,但如果你不知道你正在处理的类型,那么你很有可能会遇到问题 - 并非在所有情况下,但是那里有足够的气味,所以你应该怀疑。

于 2010-05-19T13:52:37.477 回答
2

除了可读性问题之外,使用“var”还有一个真正的问题。当用于定义稍后在代码中分配的变量时,如果用于初始化变量的表达式类型更改为更窄的类型,则可能导致代码损坏。通常,重构方法以返回比以前更窄的类型是安全的:例如,用某个类“Foo”替换返回类型“Object”。但是如果有一个变量的类型是根据方法推断出来的,那么改变返回类型就意味着这个变量可以再被分配一个非Foo对象:

var x = getFoo(); // Originally declared to return Object
x = getNonFoo();

所以在这个例子中,改变 getFoo 的返回类型会使 getNonFoo 的赋值非法。

如果 getFoo 及其所有用途都在同一个项目中,这没什么大不了的,但是如果 getFoo 在供外部项目使用的库中,您将无法再确定缩小返回类型不会破坏某些用户代码他们像这样使用'var'。

正是出于这个原因,当我们向 Curl 编程语言(在 Curl 中称为“def”)添加类似的类型推断功能时,我们阻止了使用这种语法定义的变量的赋值。

于 2010-05-19T14:21:45.127 回答
2

varanonymous types在 C# 3.0 和 LINQ 中引入的占位符。

因此,它允许在一个集合中为更少的列编写 LINQ 查询。无需复制内存中的信息,只需加载完成您需要完成的工作所必需的内容。

的使用var一点也不坏,因为它实际上不是一种类型,但正如其他地方所提到的,它是类型的占位符,并且必须在等式的右侧定义。然后,编译器会将关键字替换为类型本身。

即使使用 IntelliSense,类型的名称也很长,因此它特别有用。只需编写var并实例化它。之后将阅读您的代码的其他程序员将很容易理解您在做什么。

这就像使用

public object SomeObject { get; set; }

代替:

public object SomeObject {
    get {
        return _someObject;
    } 
    set {
        _someObject = value;
    }
}
private object _someObject;

每个人都知道属性在做什么,正如每个人都知道var关键字在做什么,并且任何一个示例都倾向于通过使其更轻巧来简化可读性,并使程序员编写有效的代码更加愉快。

于 2010-05-19T15:20:25.683 回答
1

在我们的办公室,我们的 CTO 已经明确禁止使用 var 关键字,原因与您所说的相同。

就我个人而言,我发现 var 的使用仅在新对象声明中有效,因为对象的类型在语句本身中是显而易见的。

对于 LINQ 查询,您可以将结果解析为:

IEnumerable<TypeReturnedBySelectObject>
于 2008-09-03T11:35:49.320 回答
1

@erlando,出于好奇,为什么您需要通过查看源代码来了解变量的类型?

在我的实践中,我发现变量类型仅在我在代码中使用它时才对我很重要。

如果我试图在someVar编译器上做一些不恰当的操作,我很乐意给我一个错误\警告。

如果我理解为什么在给定的上下文中使用它,我真的不在乎someVar的类型。

于 2008-09-03T11:55:57.167 回答
1

我在以下情况下使用 var:

  1. 当我不得不(结果是匿名的)
  2. 当类型与代码在同一行时,例如

    var emp = new Employee();

很明显我们想要一个 Employee(因为我们正在创建一个新的 Employee 对象),那么如何

Employee emp = new Employee() any more obvious?

当无法推断类型时,我不使用 var,例如

var emp = GetEmployee();

因为返回类型不是很明显(在 Employee、IEmployee、与 Employee 对象完全无关的东西等等?)。

于 2008-09-03T13:43:31.587 回答
1

我必须同意马特汉密尔顿的观点。

当与好的变量名一起使用时,Var 可以使您的代码更具可读性和可理解性。但是,如果使用不当,var 也会使您的代码像 Perl 一样难以阅读和理解。

var 的好坏用途列表也无济于事。这是一个常识性的案例。更大的问题是可读性与可写性之一。许多开发人员并不关心他们的代码是否可读。他们只是不想打字太多。就个人而言,我是一个阅读>写作的人。

于 2008-09-03T15:54:37.373 回答
1

kronoz - 在那种情况下(两者都超载)有关系吗?如果您有两个采用不同类型的重载,那么您基本上会说任何一个都可以传递并做同样的事情。

您不应该有两个根据传递的类型执行完全不同操作的重载。

虽然在这种情况下您可能会感到有些困惑,但它仍然是完全类型安全的,但您只是有人调用了错误的方法。

于 2008-09-04T12:23:15.267 回答
1

我不明白为什么人们会开始这样的辩论。它真的没有任何用处,只是在最后一无所获地开始激烈的战争。现在,如果 C# 团队试图逐步淘汰一种风格以支持另一种风格,我可以看到争论每种风格优点的原因。但既然两者都将保留在语言中,为什么不使用喜欢的语言并让每个人都这样做。这就像使用每个人最喜欢的三元运算符:有些人喜欢,有些人不喜欢。归根结底,它对编译器没有任何影响。

这就像与您的兄弟姐妹争论您最喜欢哪个父母:除非他们离婚,否则这无关紧要!

于 2008-09-09T12:55:29.747 回答
1

我发现使用 var 关键字实际上使代码更具可读性,因为您只是习惯于跳过 'var' 关键字。当您真的不关心特定类型是什么时,您无需继续向右滚动即可弄清楚代码在做什么。如果我真的需要知道下面的“项目”类型,我只需将鼠标悬停在它上面,Visual Studio 就会告诉我。换句话说,我更愿意阅读

foreach( var item in list ) { DoWork( item ); }

一遍又一遍地

foreach( KeyValuePair<string, double> entry in list ) { DoWork( Item ); }

当我试图消化代码时。我认为这在某种程度上归结为个人喜好。我会依靠常识——保存重要内容的强制标准(安全性、数据库使用、日志记录等)

-艾伦。

于 2008-09-15T21:20:47.987 回答
1

我认为人们不理解 var 关键字。他们将它与 Visual Basic / JavaScript 关键字混淆,后者完全不同。

许多人认为 var 关键字意味着弱类型(或动态类型),而实际上 c# 是并且仍然是强类型。

如果您在 javascript 中考虑这一点:

var something = 5;

您可以:

something = "hello";

在 c# 的情况下,编译器会从第一条语句推断出类型,导致某些类型为“int”类型,因此第二条语句将导致异常。

人们只需要了解使用 var 关键字并不意味着动态类型,然后决定他们想要使用 var 关键字的程度,知道它对于编译的内容绝对没有区别。

当然引入 var 关键字是为了支持匿名类型,但如果你看一下:

LedDeviceController controller = new LedDeviceController("172.17.0.1");

它非常非常冗长,我相信这同样具有可读性,如果不是更多的话:

var controller = new LedDeviceController("172.17.0.1");

结果完全相同,所以是的,我在整个代码中都使用它

更新:

也许,只是也许......他们应该使用另一个关键字,然后我们就不会进行这个讨论......也许是“推断”关键字而不是“var”

于 2008-10-17T20:20:01.903 回答
1

在这个讨论中到达有点晚了,但我只想补充一点。

对于所有反对类型推断的人(因为这就是我们在这里真正谈论的内容),那么 lambda 表达式呢?如果您坚持始终显式声明类型(匿名类型除外),那么您将如何处理 lambda?“不要让我使用鼠标悬停”参数如何适用于 var 但不适用于 lambda?

更新

我刚刚想到了一个反对“var”的论点,我认为还没有人提到过,那就是它“破坏”了“查找所有引用”,这可能意味着(例如)如果您正在检查使用情况重构之前的类,你会错过所有使用类的地方var

于 2009-04-27T09:09:18.157 回答
1

您可以让编译器(以及接下来维护代码的人)从初始化赋值的右侧推断类型。如果这种推断是可能的,编译器可以做到这一点,这样它就可以节省您的一些输入。

如果对那个可怜的家伙来说推理很容易,那么你就没有伤害任何东西。如果推理很难,那么您使代码更难维护,因此作为一般规则我不会这样做。

最后,如果您希望类型是特定的,并且您的初始化表达式实际上具有不同的类型,则使用 var 意味着您将更难找到引发的错误。通过明确地告诉编译器你想要的类型是什么,当类型不是那个时,你会立即得到诊断。通过对类型声明进行缓和并使用“var”,您将不会在初始化时遇到错误;相反,您会在某些使用 var 表达式分配的标识符的表达式中遇到类型错误,并且更难理解原因。

所以道德是,谨慎使用 var ;您通常不会对自己或下游的维护人员有很多好处。并希望他以同样的方式推理,所以你不会因为他认为使用 var 很容易而猜测他的意图。在编写使用寿命长的系统时,优化您的输入量是一个错误。

于 2009-08-19T07:25:07.610 回答
1

有时,编译器还可以比开发人员“更好”地推断出所需的内容——至少是不了解他正在使用的 api 需要什么的开发人员。

例如 - 使用 linq 时:

示例 1

Func<Person, bool> predicate = (i) => i.Id < 10;
IEnumerable<Person> result = table.Where(predicate);

示例 2

var predicate = (Person i) => i.Id < 10;
var result = table.Where(predicate);

在上面的代码中 - 假设使用 Linq to Nhibernate 或 Linq to SQL,示例 1 将带回 Person 对象的整个结果集,然后在客户端进行过滤。但是,示例 2 将在服务器上进行查询(例如在带有 SQL 的 Sql Server 上),因为编译器足够聪明,可以计算出 Where 函数应该采用 Expression> 而不是 Func。

示例 1 中的结果也将无法在服务器上进一步查询,因为返回了 IEnumerable,而在示例 2 中,编译器可以确定结果是否应该是 IQueryable 而不是 IEnumerable

于 2009-08-19T09:17:35.603 回答
1

因冗余原因删除。

vars仍然初始化为正确的变量类型 - 编译器只是从上下文中推断出它。正如您所提到的, var 使我们能够存储对匿名类实例的引用-但它也使更改代码变得更加容易。例如:

// If you change ItemLibrary to use int, you need to update this call
byte totalItemCount = ItemLibrary.GetItemCount();

// If GetItemCount changes, I don't have to update this statement.
var totalItemCount = ItemLibrary.GetItemCount();

是的,如果很难从变量的名称和用法中确定变量的类型,请务必明确声明其类型。

于 2010-05-19T13:48:28.930 回答
1

在我看来,大量使用是没有问题的var。它不是它自己的类型(您仍在使用静态类型)。相反,它只是节省时间,让编译器弄清楚要做什么。

像任何其他节省时间的工具(例如自动属性)一样,在到处使用它之前了解它是什么以及它是如何工作的是一个好主意。

于 2010-05-19T13:49:32.813 回答
1

var还不错。记住这一点。var还不错。重复。var还不错。记住这一点。var还不错。重复。

如果编译器足够聪明,可以从上下文中找出类型,那么你也是。您不必在申报时将其写下来。而智能感知使这变得更加不必要。

var还不错。记住这一点。var还不错。重复。var还不错。记住这一点。var还不错。重复。

于 2010-05-19T13:51:05.103 回答
1

如果您知道类型,请使用类型。如果你不知道类型,为什么不呢?如果你不知道类型,没关系——你找到了唯一有效的用途。

我很抱歉,但如果你能做的最好的事情是“它使代码全部对齐”,那不是一个好的答案。找到一种不同的方式来格式化您的代码。

于 2010-05-19T16:27:35.200 回答
1

一个很好的论点为什么 vars 不应该被用作单纯的“打字快捷方式”,而应该被用于它们主要设计的场景:Resharper(至少 v4.5)如果表示为变种。在重构或分析源代码时,这可能是一个真正的问题。

于 2010-07-20T09:14:43.630 回答
1

大多数人忽略了什么:

var something = new StringBuilder(); 

通常打字的速度不如

StringBuilder something = KEY'TAB'();
于 2010-08-12T09:53:44.890 回答
0

@erlando,

谈到重构,通过将新类型的实例分配给一个变量而不是在多个地方进行更改来更改变量类型似乎要容易得多,不是吗?

至于代码审查,我认为var关键字没有大问题。在代码审查期间,我更喜欢检查代码逻辑而不是变量类型。当然,开发人员可能会使用不适当的类型,但我认为这种情况的数量非常少,这不是我停止使用var关键字的理由。

所以我重复我的问题。为什么变量类型对你很重要?

于 2008-09-03T12:07:46.967 回答
0

@基思-

在 IEnumerable<int> 和 IEnumerable<double> 之间的比较中,您无需担心 - 如果您传递了错误的类型,您的代码无论如何都不会编译。

这并不完全正确 - 如果一个方法同时被重载到 IEnumerable<int> 和 IEnumerable<double> ,那么它可能会默默地将意外推断的类型(由于程序中的一些其他更改)传递给错误的重载,从而导致不正确的行为.

我想问题是这种情况出现的可能性有多大!

我想问题的一部分是 var 给给定声明增加了多少混淆 - 如果不清楚某物是什么类型(尽管是强类型并且编译器完全理解它是什么类型),有人可能会掩盖类型安全错误,或者至少需要更长的时间来理解一段代码。

于 2008-09-03T13:16:09.533 回答
0

var对于匿名类型来说是必不可少的(正如之前对这个问题的回答之一所指出的那样)。

我会将所有其他关于其利弊的讨论归类为“宗教战争”。我的意思是对……的相对优点进行比较和讨论。

var i = 5;
int j = 5;

SomeType someType = new SomeType();
var someType = new SomeType();

...完全是主观的。

隐式类型意味着使用var关键字声明的任何变量都不会受到运行时的惩罚,因此它归结为关于什么让开发人员高兴的辩论。

于 2008-11-26T16:19:16.970 回答
0

我不使用 var 因为它违背了 C# - C/C++/Java 的根源。即使它是一个编译器技巧,它也会让语言感觉它的类型不那么强。也许 20 多年的 C 语言已经深深地烙印在我们(反 var 人)的脑海中,我们应该在等号的左侧和右侧都有这种类型。

话虽如此,我可以看到长通用集合定义和长类名(如 codinghorror.com 示例)的优点,但在其他地方(如 string/int/bool)我真的看不出重点。特别

foreach (var s in stringArray)
{

}

节省 3 个字符!

对我来说,主要的烦恼是无法看到 var 代表方法调用的类型,除非您将鼠标悬停在方法上或 F12 上。

于 2009-01-31T11:54:34.210 回答
0

当您将鼠标悬停在“var”上时,带有 resharper 4.1 的 VS2008 在工具提示中输入正确,因此我认为当您查找类的所有用法时它应该能够找到它。

不过,尚未测试它是否可以做到这一点。

于 2009-02-11T15:49:39.783 回答
0

取决于,它以某种方式使代码看起来“更干净”,但同意它使它更难以阅读......

于 2009-06-09T19:08:19.070 回答
0

它可以使代码更简单、更短,尤其是对于复杂的泛型类型和委托。

此外,它使变量类型更容易更改。

于 2009-06-09T19:10:03.950 回答
0

var当您不想重复自己时,这很棒。例如,我昨天需要一个与此类似的数据结构。你更喜欢哪种代表?

Dictionary<string, Dictionary<string, List<MyNewType>>> collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

或者

var collection = new Dictionary<string, Dictionary<string, List<MyNewType>>>();

var请注意,在此示例中使用很少会引起歧义。但是,有时这不是一个好主意。例如,如果我var按以下方式使用,

var value= 5;

当我可以写出真正的类型并消除5应该如何表示的任何歧义时。

double value = 5;
于 2009-06-09T19:11:36.427 回答
0

我不认为 var per say 是一个糟糕的语言特性,因为我每天都使用它来编写 Jeff Yates 所描述的代码。实际上,几乎每次我使用 var 都是因为泛型可以编写一些非常冗长的代码。我的代码很冗长,但泛型走得太远了。

也就是说,我(显然......)认为 var 已经成熟,可以滥用了。如果代码在一个方法中达到 20 多行,而 vars 乱七八糟,你很快就会让维护成为一场噩梦。此外,教程中的 var 非常反直觉,在我的书中通常是一个巨大的禁忌。

另一方面,var 是一个“简单”的功能,新程序员会抓住并喜欢它。然后,在几分钟/几小时/几天内,当他们开始达到极限时,就会遇到巨大的障碍。“为什么我不能从函数中返回 var?” 那样的问题。此外,向强类型语言添加伪动态类型很容易让新开发人员绊倒。从长远来看,我认为 var 关键字实际上会让新程序员更难学习 c#。

也就是说,作为一名经验丰富的程序员,我确实使用 var,主要是在处理泛型(以及显然是匿名类型)时。我确实坚持我的报价,我相信 var 将是最严重的滥用 c# 功能之一。

于 2009-06-09T19:20:33.757 回答
0

基本 LINQ

除非绝对必要,否则最好不要显式声明范围变量的类型。例如,以下代码可以干净地编译,但编译器可以在没有正式声明的情况下推断出类型:

List<string> list = new List<string> { "LINQ", "query", "adventure" };
var query = from string word in list
      where word.Contains("r")
      orderby word ascending
      select word;

显式声明范围变量的类型会强制对 LINQ Cast 运算符进行幕后调用。此调用可能会产生意想不到的后果并可能会损害性能。如果您在使用 LINQ 查询时遇到性能问题,此处所示的强制转换是开始寻找罪魁祸首的一个可能的地方。(此规则的一个例外是当您使用非泛型 Enumerable 时,在这种情况下您应该使用强制转换。)

于 2009-06-23T08:19:04.963 回答
0

您不必写出类型名称,并且由于类型在编译时被解析,因此性能不会降低。

于 2009-08-19T07:14:33.840 回答
0

第一的。

var不是一种类型,也不是一些特殊功能(如 c# 4.0 dynamic)。它只是一个语法糖。您要求编译器通过右侧表达式推断类型。唯一需要的地方是匿名类型。

我不认为使用var既不好也不坏,它是编码风格。我个人不使用它,但我不介意其他团队成员使用它。

于 2010-05-19T13:52:21.587 回答
0

埃里克的答案在这里......

C# 中泛型类型的命名空间范围别名

相关的。

部分问题是 C# 中没有强类型别名。如此多的开发人员使用var作为部分代理。

于 2010-05-19T14:51:25.303 回答
0

这没有错,但可能不合适。有关示例,请参阅所有其他响应。

变量 x = 5; (坏的)

var x = new SuperDooperClass(); (好的)

var x = from t in db.Something select new { Property1 = t.Field12 }; (更好的)

于 2010-05-19T15:09:12.260 回答
0

“关于我的品味,你唯一能真正说的就是它是老式的,随着时间的推移,你的也会是。” ——托尔金。

于 2010-05-19T15:10:59.143 回答
0

var很好,因为它遵循经典的DRY规则,当您在声明变量的同一行中指示类型时,它特别优雅。(例如var city = new City()

于 2010-05-19T16:03:14.943 回答
0

var 是处理匿名类型的方法,无论是否来自 LINQ 语句。任何其他用途在很大程度上取决于谁将阅读您的代码以及制定了哪些准则。

如果您是唯一的听众,或者您的听众对使用 var 感到满意,或者对您的代码非常熟悉,那么我想这并不重要。如果你像这样使用它:var s = new SqlConnection()那么它在很大程度上并不重要,并且可能会提高代码的可读性。如果人们不太挑剔,并且可以让他们在不明显时做一些工作来了解类型(在大多数情况下不需要,您在以下语句中如何使用它通常会解释一切),那么没关系.

但是如果你有挑剔、心胸狭窄的队友喜欢发牢骚,或者如果你公司的设计指南明确禁止在类型不明显时使用 var,那么你很可能会遇到强烈反对。

如果使用 var 让你的代码非常难以阅读,你可能会被使用 var 击中,即使它可能是你的应用程序设计的罪魁祸首。

如果 var 引入歧义(有点像您的 IEnumerable/IEnumerable 示例),请不要使用它并且要明确。但是 var 确实有它的便利性,在某些情况下,恕我直言,甚至通过减少混乱来提高可读性。

于 2011-11-21T05:41:27.640 回答
0

局部变量可以被赋予 var 的推断“类型”而不是显式类型。var 关键字指示编译器从初始化语句右侧的表达式推断变量的类型。

// z 被编译为 int

var z = 100;

// s 被编译为下面的字符串

var s = "Hello";

// a 被编译为 int[]

var a = new[] { 0, 1, 2 };

// expr 被编译为 IEnumerable // 或者可能是 IQueryable

var expr =
    from c in customers
    where c.City == "London"
    select c;

// anon 被编译为匿名类型

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

// list 编译为 List

var list = new List<int>();

var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.

var 不能用于类范围内的字段。

使用 var 声明的变量不能在初始化表达式中使用。换句话说,这个表达式是合法的: int i = (i = 20); 但是这个表达式会产生编译时错误: var i = (i = 20);

不能在同一语句中初始化多个隐式类型变量。

如果名为 var 的类型在范围内,则 var 关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。

于 2011-11-28T09:59:08.577 回答
-1

不要使用它,使您的代码不可读。

总是使用尽可能严格的打字,拐杖只会让你的生活变得地狱。

于 2010-05-19T15:05:52.623 回答
-5

如果您很懒惰并且将 var 用于匿名类型以外的任何类型,则应该要求您在命名此类变量时使用匈牙利符号。

var iCounter = 0;

生活!

男孩,我想念VB吗?

于 2010-07-29T21:14:39.607 回答