为什么ReSharper想要将'var'用于一切?

时间:2009-12-09 13:24:22

标签: c# .net visual-studio resharper var

我刚开始在Visual Studio中使用ReSharper(在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);

依此类推,即使是intbool等简单类型。

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

23 个答案:

答案 0 :(得分:276)

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

var obj = new SomeObject();

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

SomeObject obj = DB.SomeClass.GetObject(42);

答案 1 :(得分:180)

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

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

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

答案 2 :(得分:93)

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

我更喜欢选择何时使用var,何时不使用{{1}}。但同样,那只是我。

答案 3 :(得分:67)

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默认使用它?我建议放心,因为它无法解析情况的细微差别,以决定何时最好不要使用它。

答案 4 :(得分:38)

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

ReSharper Options Menu

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

Turn off implicitly typed local variable suggestion

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

答案 5 :(得分:23)

<强>&#39;无功&#39;是清楚

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

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

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

谁走了另一条路?杰克还是比尔?在这种情况下使用名称&#34; Jake&#34;和&#34;比尔&#34;就像使用类型名称一样。并且&#34;他&#34;和&#34;他&#34;就像使用var关键字一样。在这种情况下,它可能有助于更具体。以下例如更清楚。

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

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

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

在这种情况下,如果我们使用&#34;他会更容易阅读句子。并且在某些情况下,他们一起遗漏了他的名字,这相当于使用var关键字。

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

这些例子涵盖了要点,但他们并不能讲述整个故事。在这些例子中,只有一种方式可以引用这个人。要么通过使用他们的名字,要么使用更像一般的术语,例如&#34;他&#34;和&#34;他&#34;。

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

Person p = GetPerson();

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

以下代码行怎么样?在这种情况下,您是否仍然知道p的含义:

var p = GetPerson();

现在怎么样:

var p = Get();

或者现在:

var person = Get();

或者这个:

var t = GetPerson();

或者这个:

var u = Person.Get();

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

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

有人说,有时候根据上下文我会做出例外情况,这就是任何复杂事物的本质,如果不复杂,软件就没有任何意义。

答案 6 :(得分:23)

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

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

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

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

答案 7 :(得分:17)

我也不喜欢这个。

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

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

修改:ReSharper and var

答案 8 :(得分:13)

我的规则是:

  • 您是否声明了原始类型(即bytecharstringint[]double?decimal,等等。)? - &GT;使用类型:

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

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    

答案 9 :(得分:12)

我只想指出,当变量的类型从赋值的右侧显而易见,或者当精确类型不是时,建议在C# Coding Conventions中使用“var”。重要的“,这可能是ReSharper默认启用提示的原因。它们还提供了一些不会在同一文档中提高可读性的情况。

答案 10 :(得分:12)

我看到很多正确的答案,但错过了完整答案。

确实,Resharper默认使用var。我想大多数人会同意这一点。当使用var并且类型很明显时(例如使用新语句时),它也更容易阅读。我看到一篇帖子显示了如何更新检查严重性,只显示使用var。

的提示

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

我将解释如何到达那里。

在Visual Studio中 - &gt;主菜单 - &gt; Resharper - &gt;选项 - &gt;代码编辑 - &gt; C# - &gt;代码风格 - &gt;声明中的Var用法

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

enter image description here

答案 11 :(得分:6)

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

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

答案 12 :(得分:6)

ReSharper推荐var,因为它倾向于整理对象创建。

比较以下两个例子:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

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

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

答案 13 :(得分:5)

.Net 3.0的var功能只是type inference,它是类型安全的,通常可以让您的代码更易于阅读。但是你没必要,如果你愿意,可以在resharper中关闭那个推荐。

答案 14 :(得分:3)

Var太神奇了!我遇到过许多开发人员,他们认为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 it evaluates each row to return a value per row等领域。没有var,就不能使用它们。

然而,有时显然声明类型是有用的,我发现这在基元或结构中最有用。例如,我个人认为这种语法非常有用:

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

}

VS

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

}

这完全取决于个人偏好,但使用var确实会加快您的开发速度,并打开一个匿名类型善良的整个世界。

答案 15 :(得分:2)

在我看来,var只应在明确定义变量值时的类型时使用。

示例:

var s = "string value";

很明显sstring

我认为当变量类型名称非常复杂时也适用。

示例:

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进行任何GAIN,但我可以想到一些可能有害的情况: < / p>

例如,一种一次性类型,其右侧变量值不能清楚地显示类型。处置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.

答案 16 :(得分:2)

没有技术差异,如果使用var,编译器会暗示类型。如果您有这样的代码:

var x = 1;

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

如果更改变量的类型,var关键字很有用;然后你只需做一次改变而不是两次:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";

答案 17 :(得分:2)

指定显式对象类型在某种程度上是多余的。即使用英语翻译,它听起来也是多余的:“将X类型的对象放在X类型的变量中”vs“将X类型的对象放在变量中”。

但是,使用'var'有限制。它阻止了以下多态的使用,这是纯美

假设一只狗延伸动物; 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'。 : - )

答案 18 :(得分:2)

{C} 3.0引入了var关键字 - 它让我们忘记了明确指定我们的类型。

使用

没有什么区别

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 reference

答案 19 :(得分:1)

对于那些不喜欢不断使用“var”的人:

注意:在执行“引入变量”时,您也可以停止resharper从默认为var。这让我很长一段时间感到沮丧,它总是默认为var,我每次都在改变它。

这些设置位于代码编辑 - &gt; C# - &gt;代码风格

enter image description here

答案 20 :(得分:1)

'var'在您的代码中添加了一种“动态”元素(尽管代码当然仍然严格输入)。我建议不要在类型不明确的情况下使用它。考虑以下示例:

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

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

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

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

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

以下使用var应该总是可以的:

var abc = new Something();

答案 21 :(得分:0)

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

来自website

  

使用C#3.0中引入的隐式类型局部变量(也称为var关键字)已经变得非常流行,因为结果代码的可读性得到了提高。默认情况下,ReSharper还鼓励使用var关键字,但其使用的首选项可灵活配置。例如,您可以选择在特定情况下或在任何地方使用显式类型。

答案 22 :(得分:0)

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

在我看来,主要的好处是,这往往会迫使你使用更好的变量命名。在你的例子中,'foo'是变量名的一个非常糟糕的选择。