Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么ReSharper要使用';var';为了一切?_C#_.net_Visual Studio_Resharper_Var - Fatal编程技术网

C# 为什么ReSharper要使用';var';为了一切?

C# 为什么ReSharper要使用';var';为了一切?,c#,.net,visual-studio,resharper,var,C#,.net,Visual Studio,Resharper,Var,我刚刚开始在VisualStudio中使用ReSharper(在提出了许多建议之后)。为了尝试一下,我打开了一个最近的ASP.NETMVC项目。我注意到的第一件也是最常见的一件事是将大部分/所有显式声明改为var。例如: //From This: MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1); //To This: var foo = DB.MyObjects.SingleOrDefault(w => w.Id

我刚刚开始在VisualStudio中使用ReSharper(在提出了许多建议之后)。为了尝试一下,我打开了一个最近的ASP.NETMVC项目。我注意到的第一件也是最常见的一件事是将大部分/所有显式声明改为
var
。例如:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
Person p = GetPerson();
等等,即使使用简单的类型,例如
int
bool
,等等


为什么建议这样做?我没有计算机科学或.NET背景,最近“陷入了.NET开发中”,所以我真的很想了解正在发生的事情以及它是否有益。

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

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

var dictionary=newdictionary();

没有技术上的区别,如果使用var,类型由编译器暗示。如果您有这样的代码:

var x = 1;
x暗示为int,不能为其指定其他值

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

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

我个人更倾向于关闭这个建议。使用
var
通常可以提高可读性;但正如您所提到的,它有时会减少它(使用简单类型,或者当生成的类型不清楚时)


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

我也不喜欢这样

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

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


编辑:

ReSharper建议使用
var
,因为它会使对象创建变得整洁

比较这两个例子:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();
这只是一个速记,应该更容易阅读


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

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

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

var obj = new SomeObject();
如果类型不明显,则应写出:

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

顺便说一句,ReSharper区分了“您可能希望将此建议应用于您的代码”和“您的代码已损坏,希望我修复它吗?”。
var
关键字与“invert if to reduce nesting”等内容一起属于建议类别;你不必遵循它


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

在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";
返回
字符串
类型


没有技术上的区别(正如伊渥尔人指出的那样)。您可以使用其中一个,生成的CLR代码看起来是一样的


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

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

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


除此之外,可读性的提高是一个重要的方面,但正如其他人所说,var不应该被过度使用,因此我认为在Resharper中关闭提示是完全可以的。

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

然而,使用“var”有其局限性。它防止以下使用多态性,即纯美

假设狗是动物;Cat扩展了动物类层次结构:

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”。:-)

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

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

例如,错误的命名会导致
var
导致代码理解能力下降。这不是var的错误
var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 
var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 
    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 o = new { Num=3, Name="" };
string myStr = "foo";
int[] myIntArray = [123, 456, 789];
double? myDouble = 123.3;
var myList = List<string>();
var myDictionary = Dictionary<string, string>();
var myObjInstance = new MyObj();
Person p = GetPerson();
var p = GetPerson();
var p = Get();
var person = Get();
var t = GetPerson();
var u = Person.Get();
var s = "string value";
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>>>();
// 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.
for(var i = 0; i < 10; i++) 
{

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

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

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

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}
var abc = new Something();