c# - 为什么ReSharper想要使用'var'来做所有事情?

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

//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开发,所以我真的很想了解正在发生的事情以及它是否有益。

Chris asked 2019-03-20T16:24:59Z
23个解决方案
270 votes

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

var obj = new SomeObject();

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

SomeObject obj = DB.SomeClass.GetObject(42);
Guffa answered 2019-03-20T16:25:45Z
174 votes

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

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

要么

var dictionary = new Dictionary<int, MyLongNamedObject>();
Mark Sherretta answered 2019-03-20T16:25:12Z
92 votes

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

我喜欢选择何时使用var以及何时不使用。 但同样,那只是我。

Bryan Menard answered 2019-03-20T16:26:19Z
66 votes

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

John K answered 2019-03-20T16:27:44Z
37 votes

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

ReSharper Options Menu

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

Turn off implicitly typed local variable suggestion

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

Erikest answered 2019-03-20T16:28:26Z
22 votes

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

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

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

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

Philipp answered 2019-03-20T16:29:08Z
21 votes

'var'是清楚的

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

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

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

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

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

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

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

在这种情况下,如果我们使用“他”并且在某些情况下将所有名称全部遗漏,则更容易阅读该句子,这相当于使用var关键字。

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

这些例子涵盖了要点,但它们并不能说明整个故事。 在这些例子中,只有一种方式可以引用这个人。 要么使用他们的名字,要么使用像“他”和“他”这样的更通用的术语。

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

Person p = GetPerson();

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

以下代码行怎么样? 在这种情况下,你还会知道var的含义:

var p = GetPerson();

现在怎么样:

var p = Get();

或者现在:

var person = Get();

或者这一个:

var t = GetPerson();

或这个:

var u = Person.Get();

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

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

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

Luis Perez answered 2019-03-20T16:31:55Z
17 votes

我也不喜欢这个。

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

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

编辑:ReSharper和var

LiamB answered 2019-03-20T16:32:43Z
13 votes

我的规则是这样的:

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

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    
  • 您是否声明了复杂类型(即var myList = List<string>(); var myDictionary = Dictionary<string, string>(); var myObjInstance = new MyObj(); ,Dictionary<T, T>,MyObj)? - &GT; 使用var

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    
Sumner Evans answered 2019-03-20T16:33:42Z
12 votes

我只想指出在C#编码约定中推荐使用“var”,当变量的类型从赋值的右侧显而易见,或者当精确类型不重要时,“ 可能是为什么默认情况下ReSharper中的提示已启用。 它们还提供了一些不会在同一文档中提高可读性的情况。

jose answered 2019-03-20T16:34:12Z
11 votes

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

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

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

我会解释如何到达那里。

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

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

enter image description here

Nathan Kovac answered 2019-03-20T16:35:32Z
6 votes

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

比较这两个例子:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

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

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

Paul Sasik answered 2019-03-20T16:36:23Z
6 votes

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

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

Tim Robinson answered 2019-03-20T16:37:05Z
5 votes

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

Klaus Byskov Pedersen answered 2019-03-20T16:37:37Z
3 votes

Var太神奇了! 我遇到过许多开发人员,他们认为var绑定到动态类型,但事实并非如此。 它仍然是静态类型的,它只是由编译器决定的。

以下是使用var的一些惊人的好处

例如,更少的输入var更短且更容易阅读

var Yuk。

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

更具描述性的变量名称 - 稀薄的一个,但我认为重要的是让var的流动性在这里闪耀。 由于var有点模糊,它确实鼓励一个更具有代表性的变量名称,而不是让类型说出来。

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

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

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

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

}

VS

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

}

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

KnowHoper answered 2019-03-20T16:39:16Z
2 votes

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

var x = 1;

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

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

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
eWolf answered 2019-03-20T16:40:03Z
2 votes

string关键字是在C#3.0中引入的 - 它允许我们忘记明确指定我们的类型。

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

string

要么

string

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

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

var myInt = 23;

返回string类型,而

var myInt = "23";

返回string类型。

MSDN参考

Daniel May answered 2019-03-20T16:41:28Z
2 votes

指定显式对象类型在某种程度上是多余的。 即使用英语翻译,它听起来也是多余的:“将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'。:-)

xtrem answered 2019-03-20T16:42:28Z
1 votes

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

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

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

enter image description here

Derek answered 2019-03-20T16:43:18Z
1 votes

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

例:

var s = "string value";

很明显,varstring

我相信当变量类型名称非常复杂时它也是合适的。

例:

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,但我可以想到一些可能有害的场景:

例如,一种一次性类型,其右侧变量值不能清楚地显示类型。 处置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.
James Wierzba answered 2019-03-20T16:44:28Z
0 votes

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

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

Jaco Pretorius answered 2019-03-20T16:45:08Z
0 votes

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

从他们的网站:

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

Jeff Reddy answered 2019-03-20T16:46:04Z
0 votes

'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();
lolaldanee answered 2019-03-20T16:46:59Z
translate from https://stackoverflow.com:/questions/1873873/why-does-resharper-want-to-use-var-for-everything