225

我刚刚开始将 ReSharper 与 Visual Studio 一起使用(在许多关于 SO 的建议之后)。为了尝试它,我打开了一个最近的 ASP.NET MVC 项目。我注意到它建议的第一个也是最常见的事情之一是将我的大部分/所有显式声明改为var改为。例如:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

等等,即使是简单的类型,如int,bool等。

为什么推荐这个?我不是来自计算机科学或.NET 背景,最近“陷入”.NET 开发,所以我真的很想了解发生了什么以及它是否有益。

4

23 回答 23

294

ReSharper 的建议显然是过度使用了 var 关键字。您可以在类型明显的地方使用它:

var obj = new SomeObject();

如果类型不明显,你应该把它写出来:

SomeObject obj = DB.SomeClass.GetObject(42);
于 2009-12-09T13:29:59.340 回答
198

一个原因是提高了可读性。哪个更好?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

或者

var dictionary = new Dictionary<int, MyLongNamedObject>();
于 2009-12-09T13:26:32.110 回答
101

我个人更喜欢关闭这个建议。使用var通常可以提高可读性;但正如您所提到的,它有时会减少它(使用简单类型,或者当结果类型是obscure时)。

我更喜欢选择何时使用var和何时不使用。但同样,这只是我。

于 2009-12-09T13:28:30.047 回答
70

var可以增加代码的可读性,同时降低对代码的直接理解。同样,它会降低代码在其他情况下的可读性。有时它的使用是中性的。对理解的可读性的衡量不是成比例的,而是取决于情况。有时两者一起增加或减少。

因素是var应用到什么,以及目标支持对读者立即混淆其数据类型的能力,或者是否需要其类型信息来理解手头的程序部分。

例如,错误的命名会导致var代码理解能力下降。但这不是var' 的错:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

有时,var当代码在没有它的情况下更具可读性时,将其用于简单的数据类型是没有意义的:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

有时var隐藏您不一定关心查看复杂性的数据类型信息可能很有用:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

当存在匿名类型时必须使用,因为没有类型名称可以通过以下方式调用它:var

var o = new { Num=3, Name="" };

当你让 Visual Studio Intellisense 提供类型信息时var,你需要通过严格的代码阅读来减少对你的理解的依赖,而无需帮助。假设不是每个人都可能拥有或使用 Intellisense 可能是明智的。

总之,基于上述示例,我建议全权委托应用var不是一个好主意,因为大多数事情最好适度完成,并根据手头的情况进行,如此处所示。

为什么 Resharper 默认全部使用它?我建议轻松一点,因为它无法解析情况的细微差别来决定何时最好不要使用它。

于 2013-03-02T06:39:12.383 回答
42

在 ReSharper(8.02,但可能是其他版本)中,“使用隐式类型的局部变量声明”建议的选项可以根据您的偏好进行调整,无论是什么,首先打开 ReSharper 的选项菜单:

ReSharper 选项菜单

然后,在“代码检查”下,通过调整您选择的语言的“检查严重性”,在我的情况下为 c#:

关闭隐式类型的局部变量建议

如您所见,有一些选项可以调整 ReSharper 提出的所有建议。希望这可以帮助像我这样已经拥有“var”使用策略并且只希望 ReSharper 尊重它的人:)

于 2013-12-06T21:56:38.593 回答
26

'var' 是关于清楚

关于是否使用关键字的主要争论在于var代码对您和其他开发人员的可读性。

就像你在写一个故事一样,没有确定的正确答案。但是,让我们用简单的英语来看看这方面的一些例子。

杰克向比尔打招呼。他不喜欢他,所以他转身往另一条路走。

谁走的另一条路?杰克还是比尔?在这种情况下,使用名称“Jake”和“Bill”就像使用类型名称一样。而“他”和“他”就像使用var关键字一样。在这种情况下,更具体可能会有所帮助。下面的例子就更清楚了。

杰克向比尔打招呼。杰克不喜欢比尔,所以他转身走另一条路。

在这种情况下,更具体使句子更清晰。但情况并非总是如此。在某些情况下,具体化会使阅读变得更加困难。

比尔喜欢书,所以比尔去了图书馆,比尔拿出一本比尔一直很喜欢的书。

在这种情况下,如果我们使用“他”并且在某些情况下将他的名字全部省略掉,这将更容易阅读句子,这相当于使用var关键字。

比尔喜欢书,所以他去图书馆拿出一本他一直很喜欢的书。

这些例子涵盖了要点,但并不能说明全部。在这些例子中,只有一种方式来指代这个人。要么使用他们的名字,要么使用更笼统的术语,如“他”和“他”。

在代码的情况下,我们有 3 种方法来帮助增加清晰度。类型、变量名和赋值。以这行代码为例:

Person p = GetPerson();

现在的问题变成了那行代码中是否有足够的信息来帮助您弄清楚发生了什么?

下面这行代码呢?p您是否仍然知道在这种情况下是什么意思:

var p = GetPerson();

现在怎么样:

var p = Get();

或者现在:

var person = Get();

或者这个:

var t = GetPerson();

或这个:

var u = Person.Get();

关键字var在给定场景中是否有效很大程度上取决于代码的上下文,例如变量、类和方法的命名方式。它还取决于代码的复杂性以及围绕它的其他代码。

就我个人而言,我喜欢在大多数情况下使用对我来说var更全面的关键字。但我也倾向于以类型命名我的变量,所以我并没有真正丢失任何信息。

这就是说有时取决于我做出例外的上下文,这就是任何复杂事物的本质,软件即使不复杂也不算什么。

于 2016-01-08T18:22:20.970 回答
24

我很惊讶没有人提到更改实例化对象的类型也更容易,因为

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

是一种重复形式。如果我想更改AVeryLongTypeName为它的派生类之一,我只需要在使用时更改一次,var并且仍然可以访问子类的方法。

除此之外,提高可读性是很重要的一点,但正如其他人所说,不应该过度使用 var,所以我认为在 Resharper 中关闭提示是绝对可以的。

于 2011-03-11T06:24:10.150 回答
18

我也不喜欢这个。

我不希望这变成关于使用的辩论var,它有它的用途,但不应该在任何地方使用。

要记住的关键是 ReSharper 已配置为您想要的任何编码标准。

编辑:ReSharper 和 var

于 2009-12-09T13:28:55.160 回答
16

我看到很多正确的答案,但缺少完整的答案。

确实,ReSharpervar默认过度使用。我想大多数人都会同意这一点。使用时也更容易阅读,var并且类型很明显,例如在使用new语句时。我看到一篇文章展示了如何更新检查严重性以仅显示使用var.

我曾尝试先对其他帖子发表评论,以添加设置这些内容的位置,但没有声誉。显然,我也没有发布我的设置截图的声誉。

我将解释如何到达那里。

在 Visual Studio > Main Menu > Resharper > Options > Code Editing > C# > Code Style > Var Usage in declarations

  • 对于内置类型使用显式类型
  • 对于简单类型,明显时使用 'var'
  • 在其他地方使用'var'

在此处输入图像描述

ReSharper 帮助文档:Code Syntax Style: Implicit/Explicit Typing ('var' Keyword) — 配置使用 'var' 关键字的首选项

于 2015-04-08T15:02:36.510 回答
13

我的规则是这样的:

  • 您是否在声明原始类型(即byte, char, string, int[], double?, decimal, 等)?-> 使用类型:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
    
  • 您是否在声明复杂类型(即List<T>, Dictionary<T, T>, MyObj)?-> 使用var

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    
于 2015-04-14T02:00:10.073 回答
12

我只想指出,在C# 编码约定中建议使用“var”

当变量的类型从赋值的右侧很明显时,或者当精确的类型不重要时

所以这可能就是 ReSharper 中默认启用提示的原因。它们还提供了一些不会提高同一文档下方的可读性的情况。

于 2013-09-28T22:47:17.593 回答
6

ReSharper 建议使用var它,因为它倾向于整理对象创建。

比较这两个例子:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

这只是一个简写,应该更容易阅读。

我认为用“new”显式创建新对象很好。但是,在您的示例中,如果类命名不正确,可能并不明显。

于 2009-12-09T13:29:46.550 回答
6

顺便说一句,ReSharper 区分了“您可能希望将此建议应用于您的代码”和“您的代码已损坏,需要我修复它吗?”。关键字在var建议类别中,以及诸如“反转 if 以减少嵌套”之类的内容;你不必遵循它。

您可以通过“选项”对话框或直接通过该警报的弹出菜单来配置每个警报的烦人程度。您可以将var建议等内容降级,使其不那么突出,或者您可以升级“使用扩展方法”警报等内容,使其显示为实际错误。

于 2009-12-09T13:32:03.813 回答
5

.NET 3.0的var特性只是类型推断,它是类型安全的,并且通常使您的代码更易于阅读。但您不必这样做,如果您愿意,可以在 ReSharper 中关闭该建议。

于 2009-12-09T13:29:57.810 回答
4

瓦尔是惊人的!我遇到过许多开发人员,他们的印象var是绑定到动态类型,但事实并非如此。它仍然是静态类型的,只是由编译器决定。

以下是使用 var 的一些惊人优势

少打字的 var 更短更容易阅读,例如

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Yuk。

var postcodes = new Dictionary<int,IList<string>>()\o/\o/

更具描述性的变量名称- 脆弱的名称,但我认为让var这里的流动性大放异彩很重要。var有点模糊,它确实鼓励使用更具描述性的变量名称,而不是让类型自己说话。

更少的代码更改- 如果方法调用的返回类型发生更改。您只需要更改方法调用,而不是使用它的每个地方。

匿名类型——匿名类型是一个非常强大的概念,尤其是在 WebApi部分资源等领域。没有 var,它们不能被使用。

然而,有时显式声明类型很有用,我发现这在原语或结构中最有用。例如,我个人认为这种语法不是很有用:

for(var i = 0; i < 10; i++) 
{

}

对比

for(int i = 0; i < 10; i++) 
{

}

这完全取决于个人喜好,但使用var确实会加速您的发展并解锁整个匿名类型的善良世界。

于 2017-10-09T05:03:13.250 回答
3

在我看来,var只有在定义变量的值时立即清楚类型是什么时才应该使用。

例子:

var s = "string value";

很明显,这s是一个string.

我相信在变量类型名称非常复杂的情况下也是合适的。

例子:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

除了这些场景之外,我看不到使用 可以获得任何增益var,但我可以想到一些可能有害的场景:

例如,一个一次性类型,其右侧变量值没有清楚地显示类型。处置 IDisposable 很容易被遗忘

例子:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
于 2017-09-15T22:51:54.803 回答
2

没有技术上的区别,如果你使用 var,类型是编译器隐含的。如果你有这样的代码:

var x = 1;

x 隐含为 int 并且不能为其分配其他值。

如果您更改变量的类型,则 var 关键字很有用;然后,您只需进行一项更改而不是两项更改:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
于 2009-12-09T13:27:27.083 回答
2

var关键字是在 C# 3.0 中引入的——它允许我们忘记显式指定我们的类型。

您是否使用没有真正的区别

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

或者

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

除了纯粹的可读性和更少的错误机会。

这似乎是一个陈词滥调的例子,但说以下内容可能有助于您的理解:

var myInt = 23;

返回一个int类型,而

var myInt = "23";

返回一个string类型。

MSDN 参考

于 2009-12-09T13:32:17.247 回答
2

指定明确的对象类型在某种程度上是多余的。即使用英文翻译,这听起来也是多余的:“将 X 类型的对象放入 X 类型的变量中”与“将 X 类型的对象放入变量中”。

但是,使用 'var' 有其局限性。它防止了以下纯美的多态性用法:

假设 Dog 扩展 Animal;Cat 扩展了 Animal 类层次结构:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

用 'var' 声明 x 的相同代码将无法编译

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

无论如何,回到最初的问题,我不使用 Resharper,但我认为它足够聪明,可以检测何时不使用“var”。:-)

于 2013-01-27T06:57:27.383 回答
1

对于那些不喜欢不断使用“var”的人,您还可以在执行“引入变量”时阻止 ReSharper 默认为 var。这让我很沮丧很长时间,它总是默认为 var,而且我每次都在更改它。

这些设置位于代码编辑 > C# > 代码样式下

在此处输入图像描述

于 2016-01-25T11:13:06.923 回答
1

'var' 为您的代码添加了一种“动态”元素(尽管代码当然仍然是严格类型的)。我建议不要在类型不清楚的情况下使用它。考虑这个例子:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

如果 GetTheObjectFromDatabase() 的返回类型从类型 A 更改为 B,我们不会注意到,因为两个类都实现了 DoSomething()。然而,代码现在实际上可能会做一些完全不同的事情。

这可能与将不同内容写入日志一样微妙,因此您可能不会注意到为时已晚。

var 的以下使用应该始终没问题:

var abc = new Something();
于 2018-10-16T11:47:59.063 回答
0

没有技术差异(正如 eWolf 指出的那样)。您可以使用其中一种,生成的 CLR 代码看起来是一样的。

在我看来,主要的好处是这往往会迫使你使用更好的变量命名。在您的示例中,“foo”对于变量名来说是一个非常糟糕的选择。

于 2009-12-09T13:36:25.257 回答
0

根据 JetBrains(ReSharper 的作者)的说法,他们鼓励默认使用 var。

他们的网站

使用 C# 3.0 中引入的隐式类型局部变量(也称为var关键字)变得非常流行,因为它提高了许多场景中的可读性。默认情况下,ReSharper 还鼓励使用 ofvar关键字,但其使用偏好是可以灵活配置的——例如,您可以选择在特定情况下或任何地方使用显式类型,ReSharper 将帮助您强制执行您的偏好。

于 2016-10-03T18:22:41.060 回答