C# 为什么ReSharper要使用';var';为了一切?
我刚刚开始在VisualStudio中使用ReSharper(在提出了许多建议之后)。为了尝试一下,我打开了一个最近的ASP.NETMVC项目。我注意到的第一件也是最常见的一件事是将大部分/所有显式声明改为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
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();