构造类 - c#添加方法




在C#中使用var关键字 (20)

在与同事讨论在C#3中使用'var'关键字之后,我想知道人们对通过var?进行类型推断的适当用法有何看法?

例如,我比较懒惰地在可疑情况下使用var,例如: -

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

var更合理的用法如下:

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

有趣的是LINQ似乎有点灰色地带,例如: -

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

很明显,结果将会是一种实现IEnumerable的类型,但是它与声明一个新对象的var的方式并不完全相同。

当涉及到LINQ到对象时更糟,例如: -

var results = from item in someList
              where item != 3
              select item;

这并不比equivilent foreach(var中的someList){// ...} equivilent更好。

这里有一个关于类型安全性的真正问题 - 例如,如果我们要将查询的结果放入一个接受IEnumerable <int>和IEnumerable <double>的重载方法中,调用方可能会无意中传入错误的类型。

var 确实保持了强类型化,但问题是这种类型在定义时不会立即显示是危险的,当重载意味着编译器错误可能在您无意中将错误类型传递给方法时可能不会发出。


Var根本不像变体。 这个变量仍然是强类型的,只是你没有按键来获得它。 您可以将其悬停在Visual Studio中查看该类型。 如果你正在阅读印刷的代码,那么你可能需要稍微思考一下这个类型是什么。 但是只有一行声明它,并且有很多行使用它,所以给出一些体面的名字仍然是让代码更容易遵循的最佳方式。

是使用Intellisense懒惰? 它比整个名字更少打字。 还是有些工作较少但不值得批评的事情? 我认为有,var是其中之一。


Var,在我看来,在C#中是件好事 。 任何这样键入的变量仍然是强类型的,但是它从赋值的右侧获取它的类型。 由于类型信息在右侧可用,因此在大多数情况下,没有必要且过于冗长,因此也必须将其输入到左侧。 我认为这会显着提高可读性而不会降低类型安全性。

在我看来,从可读性的角度来看,使用变量和方法的良好命名约定比显式类型信息更重要。 如果我需要类型信息,我总是可以将鼠标悬停在变量上(在VS中)并获取它。 一般来说,读者不需要明确的类型信息。 对于开发人员来说,在VS中你仍然可以获得Intellisense,无论变量是如何声明的。 尽管如此,仍然有些情况下,明确声明类型是有意义的 - 也许你有一个返回List<T> ,但是你想在你的对象中将它作为IEnumerable<T>方法。 为了确保您使用的是接口,声明接口类型的变量可以使其变得明确。 或者,也许你想声明一个没有初始值的变量 - 因为它立刻根据某种条件得到一个值。 在这种情况下,你需要这种类型。 如果类型信息有用或必要,请继续使用它。 但我觉得,通常情况下这是没有必要的,而且在大多数情况下,没有它的代码更容易阅读。


@aku: One example is code reviews. Another example is refactoring scenarios.

Basically I don't want to go type-hunting with my mouse. It might not be available.


For the afficionados that think var saves time, it takes less keystrokes to type:

StringBuilder sb = new StringBuilder();

var sb = new StringBuilder();

Count em if you don't believe me...

19 versus 21

I'll explain if I have to, but just try it... (depending on the current state of your intellisense you may have to type a couple more for each one)

And it's true for every type you can think of!!

My personal feeling is that var should never be used except where the type is not known because it reduces recognition readabiltiy in code. It takes the brain longer to recognize the type than a full line. Old timers who understand machine code and bits know exactly what I am talking about. The brain processes in parallel and when you use var you force it to serialize its input. Why would anyone want to make their brain work harder? That's what computers are for.


I only use var when it's clear to see what type is used.

For example, I would use var in this case, because you can see immediately that x will be of the type "MyClass":

var x = new MyClass();

I would NOT use var in cases like this, because you have to drag the mouse over the code and look at the tooltip to see what type MyFunction returns:

var x = MyClass.MyFunction();

Especially, I never use var in cases where the right side is not even a method, but only a value:

var x = 5;

(because the compiler can't know if I want a byte, short, int or whatever)


I split var all over the places, the only questionable places for me are internal short types, eg I prefer int i = 3; over var i = 3;


It can certainly make things simpler, from code I wrote yesterday:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

This would have be extremely verbose without var .

Addendum: A little time spent with a language with real type inference (eg F#) will show just how good compilers are at getting the type of expressions right. It certainly has meant I tend to use var as much as I can, and using an explicit type now indicates that the variable is not of the initialising expression's type.


It's a matter of taste. All this fussing about the type of a variable disappears when you get used to dynamically typed languages. That is, if you ever start to like them (I'm not sure if everybody can, but I do).

C#'s var is pretty cool in that it looks like dynamic typing, but actually is static typing - the compiler enforces correct usage.

The type of your variable is not really that important (this has been said before). It should be relatively clear from the context (its interactions with other variables and methods) and its name - don't expect customerList to contain an int ...

I am still waiting to see what my boss thinks of this matter - I got a blanket "go ahead" to use any new constructs in 3.5, but what will we do about maintenance?



Stolen from the post on this issue at CodingHorror :

Unfortunately, you and everyone else pretty much got it wrong. While I agree with you that redundancy is not a good thing, the better way to solve this issue would have been to do something like the following:

MyObject m = new();

Or if you are passing parameters:

Person p = new("FirstName", "LastName);

Where in the creation of a new object, the compiler infers the type from the left-hand side, and not the right. This has other advantages over "var", in that it could be used in field declarations as well (there are also some other areas that it could be useful as well, but I won't get into it here).

In the end, it just wasn't intended to reduce redundancy. Don't get me wrong, "var" is VERY important in C# for anonymous types/projections, but the use here is just WAY off (and I've been saying this for a long, long time) as you obfuscate the type that is being used. Having to type it twice is too often, but declaring it zero times is too few.

Nicholas Paldino .NET/C# MVP on June 20, 2008 08:00 AM

I guess if your main concern is to have to type less -- then there isn't any argument that's going to sway you from using it.

If you are only going to ever be the person who looks at your code, then who cares? Otherwise, in a case like this:

var people = Managers.People

it's fine, but in a case like this:

var fc = Factory.Run();

it short circuits any immediate type deductions my brain could begin forming from the 'English' of the code.

Otherwise, just use your best judgment and programming 'courtesy' towards others who might have to work on your project.


Use it for anonymous types - that's what it's there for. Anything else is a use too far. Like many people who grew up on C, I'm used to looking at the left of the declaration for the type. I don't look at the right side unless I have to. Using var for any old declaration makes me do that all the time, which I personally find uncomfortable.

Those saying 'it doesn't matter, use what you're happy with' are not seeing the whole picture. Everyone will pick up other people's code at one point or another and have to deal with whatever decisions they made at the time they wrote it. It's bad enough having to deal with radically different naming conventions, or - the classic gripe - bracing styles, without adding the whole ' var or not' thing into the mix. The worst case will be where one programmer didn't use var and then along comes a maintainer who loves it, and extends the code using it. So now you have an unholy mess.

Standards are a good thing precisely because they mean you're that much more likely to be able to pick up random code and be able to grok it quickly. The more things that are different, the harder that gets. And moving to the 'var everywhere' style makes a big difference.

I don't mind dynamic typing, and I don't mind implict typing - in languages that are designed for them. I quite like Python. But C# was designed as a statically explicitly-typed language and that's how it should stay. Breaking the rules for anonymous types was bad enough; letting people take that still further and break the idioms of the language even more is something I'm not happy with. Now that the genie is out of the bottle, it'll never go back in. C# will become balkanised into camps. 不好。


Using var instead of explicit type makes refactorings much easier (therefore I must contradict the previous posters who meant it made no difference or it was purely "syntactic sugar").

You can change the return type of your methods without changing every file where this method is called. 想像

...
List<MyClass> SomeMethod() { ... }
...

which is used like

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

If you wanted to refactor SomeMethod() to return an IEnumerable<MySecondClass> , you would have to change the variable declaration (also inside the foreach ) in every place you used the method.

If you write

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

instead, you don't have to change it.


如果有人使用var关键字是因为他们不想“弄清楚类型”,那肯定是错误的原因。 var关键字不会创建具有动态类型的变量,编译器仍然需要知道类型。 由于变量总是具有特定类型,因此如果可能的话,该类型在代码中也应该是明显的。

例如,使用var关键字的好理由是:

  • 在需要的地方,即为匿名类型声明参考。
  • 它使代码更具可读性,即去除重复声明。

写出数据类型通常会使代码更容易遵循。 它显示了您正在使用的数据类型,因此您不必通过首先确定代码的功能来确定数据类型。


当然, int很容易,但是当变量的类型是IEnumerable<MyStupidLongNamedGenericClass<int, string>> ,var变得更容易。


我广泛使用var 。 有人批评这会降低代码的可读性,但没有理由支持这一说法。

诚然,这可能意味着我们不清楚我们正在处理什么类型。 所以呢? 这实际上是一个分离设计的重点。 在处理接口时,你强调对变量的类型感兴趣。 var更进一步,这是真的,但我认为从可读性的角度来看,论点仍然是一样的:程序员实际上不应该对变量的类型感兴趣,而应该关注变量的作用 。 这就是为什么微软也称为类型推断“鸭子打字”。

那么,当我使用var声明它时,变量会做什么? 很简单,它可以做任何IntelliSense告诉我它。 任何关于C#忽略IDE的推理都不符合现实。 实际上,每个C#代码都在支持智能感知的IDE中编程。

如果我正在使用一个var声明的变量并且弄不清变量是什么,那么我的代码就有一些根本错误。 var不是原因,它只是使症状可见。 不要责怪使者。

现在,C#团队发布了一个编码指南,指出该var 只能用于捕获创建匿名类型的LINQ语句的结果(因为这里我们没有真正的var替代)。 那么,拧紧。 只要C#团队没有给我这个指导方针一个合理的论点,我就会忽略它,因为在我的专业和个人意见中,这纯粹是胡扯。 (对不起,我没有链接到有关指南。)

实际上,为什么你不应该使用var有一些(表面上) 很好的解释 ,但我仍然认为它们在很大程度上是错误的。 以“searchabililty”为例:作者声称var很难搜索使用MyType地方。 对。 接口也是如此。 其实,为什么我想知道课堂在哪里? 我可能更感兴趣的是它在哪里实例化,这仍然是可搜索的,因为它的构造函数必须被调用(即使这是间接完成的,类型名称必须在某处提及)。


我看不出有什么大不了的。

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

你仍然对“某事”有完全的智能感知,对于任何含糊不清的情况,你有单元测试,对吗? ( 你做? )

它不是varchar,它不暗淡,而且它不是动态或弱类型。 它正在阻止maddnes这样:

List<somethinglongtypename> v = new List<somethinglongtypename>();

并将这个总体思路减少到:

var v = new List<somethinglongtypename>();

不错,不如:

v = List<somethinglongtypename>();

但那就是Boo目的。


我认为var的使用应该与明智选择的变量名称结合使用。

在foreach语句中使用var没有问题,前提是它不是这样的:

foreach (var c in list) { ... }

如果它更像这样:

foreach (var customer in list) { ... }

...然后有人阅读代码将更有可能理解“列表”是什么。 如果你可以控制列表变量本身的名字,那更好。

这同样适用于其他情况。 这很无用:

var x = SaveFoo(foo);

...但这是有道理的:

var saveSucceeded = SaveFoo(foo);

我想每个人都是他自己的。 我发现自己这样做,这是疯了:

var f = (float)3;

我需要某种12步的var程序。 我的名字是马特,我(ab)使用var。


最需要的时间是匿名类型(需要100%); 但它也避免了琐碎事件的重复,并使IMO更清晰。 对于简单的初始化,我不需要两次查看类型。

例如:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(请不要编辑上面的hscroll - 它有点证明了这一点!!!)

VS:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

然而,有些时候这是误导性的,并且可能会导致错误。 如果原始变量和初始化类型不相同,请小心使用var 。 例如:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

这些都不是绝对正确的。 var对可读性有正面和负面的影响。 在我看来,当以下任一情况属实时,应该使用var

  1. 该类型是匿名的(好吧,您在这里没有任何选择,因为在这种情况下它必须是var)
  2. 类型很明显基于赋值表达式(即var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating()

var没有性能影响,因为它是句法糖; 编译器推断该类型,并在编译为IL时将其定义; 实际上没有什么动态的。


这并不坏,它更像是一种文体,它往往是主观的。 它可以增加不一致性,当你使用var和不使用时。

另一个值得关注的情况是,在接下来的调用中,您无法仅仅通过查看CallMe返回的代码来判断:

var variable = CallMe();

这是我对var的主要抱怨。

当我在方法中声明匿名委托时,我使用var,不知何故var比使用Func更清晰。 考虑这个代码:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

编辑 :更新基于朱利安输入的最后一个代码示例





var