标签云

微信群

扫码加入我们

WeChat QR Code


Using var is fine, but "I don't have to figure out the type" seems like a very bad reason to use it... you're supposed to know what the type is, var is just a shortcut to avoid typing it

2018年09月26日58分40秒

var i = 0; == fail! var c = new CrazyFrigginLongClassName(); == win!

2018年09月25日58分40秒

"Var also reminds me of the VB/VBA variant type. It also had its place. I recall (from many years ago) its usage being less-than-desirable type and it was rather resource hungry." <- shows this is a baiting question as the 'var' type of C# has nothing to do with the VB/VBA variant type.

2018年09月26日58分40秒

var readabilityBeDamned = true;

2018年09月25日58分40秒

The problem with all the examples stated here is that we're looking at ONE line of code. When I see line after line of "var" declarations, one after the other, it gets out of hand. Readability is subjective, but I find var abused far more than used respectably.

2018年09月25日58分40秒

I like having the explicit type in front of me when I'm reading code. How do I know what "cust.Orders" is here without the type? Yes, I could hover my mouse over to find out, but why should I have to? :)

2018年09月25日58分40秒

But the point is that in general it doesn't matter. Provided cust.Orders is something you can enumerate (eg foreach over) then it doesn't matter what type it is. The extra code just gets in the way of reading the intent.

2018年09月25日58分40秒

But if you only require that cust.Orders is "something you can enumerate" then doesn't declaring it as an IEnumerable<Order> make that requirement explicit and clear? Declaring it as var means you effectively lose that requirement.

2018年09月25日58分40秒

jon and how would IEnumerbal orders = cust.Orders foreach(var order in orders) make a difference? the only thing IEnumerable says is that you can put it in a foreach but you already knew that from the line below

2018年09月25日58分40秒

"the only thing IEnumerable says is that you can put it in a foreach" - it also expresses the intention that the only thing you can do is enumerate. Using var gives access to and intellisense for public members of the concrete collection type.

2018年09月26日58分40秒

In any decent IDE, you don't use a text search to obtain class usage, you get the IDE to do it based on it's parse tree or however else it identifies the types of objects. Since we're talking about static typing, this will find everything but the anonymous types.

2018年09月25日58分40秒

I'd hate to inherit 100k lines of source with no documentation and liberal use of var. Especially if you combine var with less-than-helpful variable names. I could see it being helpful when illustrating a point (or dealing with anonymous types) but in production code?

1970年01月01日00分03秒

Arnshea: well you've already pointed to the real problem there: the useless variable names, and the missing documentation. I really fail to see what var contributes to the confusion. Certainly, there may be cases where it is important to emphasize the type/size of a variable (e.g. low-level bit operations). That's fine: nobody ever claimed that var should be used exclusively. The rule is simple: if it really causes confusion, don't use it.

2018年09月26日58分40秒

Every example opposed to var I've seen assumes that the programmer will be using meaningless variable names. But maybe this is why var is better than explicitly specifying a type: It forces the programmer to come up with good variable names.

2018年09月26日58分40秒

Microsoft also calls type inference “duck typing.” — do they really? I'd be shocked...

2018年09月26日58分40秒

I agree overall. The key point here in my opinion is to be certain that intent is clear. If it isn't clear to the majority developers on the team, then it is detrimental, not helpful. That said, I personally am a HUGE fan of this, but have had to rein myself in a bit when other devs on my team have had trouble determining my intent. Go figure.

2018年09月25日58分40秒

Eh, I find it easier to read when the type is on the left. Using ReSharper, I don't have to retype the type on the right anyways, so it doesn't bother me.

2018年09月25日58分40秒

BlueRaja - I find that using good variable names usually eliminates the need to bother with the actual type anyway for understanding. Intellisense is still available on "var" defined variables, so I don't need to know the type to choose a method/property on it when coding.

2018年09月25日58分40秒

It is not so much about when you are coding as it is when you have to read the code.

2018年09月25日58分40秒

I must just be on thick side then, I need to good Method and variable names and an understanding of the types being operated on to be able to properly understand the code I'm reading. I think you are right though it is symptomatic of bigger problems. One of trust. To be sure that the code is doing what it appears to be doing you need to be sure of the types being used.

2018年09月26日58分40秒

agree on both, though I have long restrictions over the second case, if a type is that long the it's usually a generic type with lots of nested generic arguments, in that case a strongly typed "ShortType equivalent to TypeWithAReallyLongNameTheresNoSenseRepeating" makes more sense

2018年09月25日58分40秒

I have no desire to start a religious war, but I personnaly tend to disagree with Ion. I would much prefer a very long, but very precise type name (ala Uncle Bob Martin) than an abbreviated and possibly ambiguous shorter type name. I will add the caveat that I DON'T agree with artificially inflating the length of the name either. If 5 characters creates a concise name that clearly shows intent, then use 5 and not 25.

2018年09月25日58分40秒

Steve: I have to agree with you; creating a "short type" (which I assume you mean as inheriting from the specific generic type solely for the purpose of shortening the name) is not a good practice; it will require you to duplicate and pass through any constructors from the generic type, as well as preventing you from passing a different type that inherits from the generic type to the function. You're using inheritance like a typedef when it isn't.

2018年09月26日58分40秒

Use var when the type is obvious? Maybe, but the true gain is when the type doesn't matter. If you're doing things like var customers = whatever; var query = from c in customers select stuff it doesn't matter what the exact type of 'customers' is. It's obvious how you can use it, and that's enough. And if the actual type is cumbersome, it's worthwhile to suppress it.

2018年09月25日58分40秒

Kristoffer: I can understand wanting to eliminate the mess of tags, but wrapping them into a class is not (IMO) an acceptable alternative, as you then cut off the possibility of any other (legitimate) child class of that generic type from being a valid parameter. I would rather use an using ShortType = LongGenericType<A,B,C> directive at the top of a file, since that gives the same readability, doesn't require that you recreate the constructors, and doesn't eliminate child classes from being candidates.

2018年09月26日58分40秒

I find Lippert's argument odd. No one types the second class name, they let Intellisense write it for them, but then he turns around and claims that var is better because the compiler/Intellisense works it out. You can't have it both ways!

2018年09月25日58分40秒

The C# team doesn't control intellisense, they control the compiler. In any event that's not the main issue. I don't think var would have made the 100 points on saving typing alone.

2018年09月25日58分40秒

Dustman: var doesn't save typing at all. It makes you write more!

2018年09月26日58分40秒

Well the only thing wrong with "var f = (float)3;" is that it should be "var f = 3f" or "var f = 3.0 (cause single precision sucks)".

2018年09月25日58分40秒

Heh yeah 3f or 3.0 is the way to go! Us var maniacs have to stick together!

2018年09月25日58分40秒

The real problem in that first example is "list", not "c". "list" of what? "list" should be renamed to "customers", or "customersWhoOweMoney", or "currentCustomers", or something far more descriptive. And once you have that, the "c" can stay as-is, because you already know what it'll contain.

2018年09月25日58分40秒

Hi Matt! My name is Kenny and I'm a varaddict.

2018年09月25日58分40秒

var MattHamil = "Luke Skywalker"; //stripped a ton out of it

2018年09月25日58分40秒

I've found that ("Code for people, not machines") to be an excellent guideline - following it can result in better code and helps avoid premature optimization.

1970年01月01日00分03秒

I don't get var list = new KeyValuePair<string, double>? For me a list can have more than on thing.

2018年09月26日58分40秒

"Code for people, not machines" - amen.

2018年09月26日58分40秒

But do you really need to know the type right there at that line? You know that CallMe returns something; isn't it enough to know that a local variable named variable is created? Unless you expand your example, this isn't a very solid complaint, IMO.

2018年09月25日58分40秒

It's not about not being verbose, it's about not letting the compiler do the syntax sugar for you. Consider this: var getter..., now this Func<object> getter..., with the second you know you don't have to provide any parameters and what it returns. You know from the start "what to do" and can make decisions faster, when designing something or refactoring. Having all the information at hand is more important than a few more characters. This only can be appreciated when you're working with lots of code.

2018年09月25日58分40秒

Since we are all talking about visual studio anyway, what's the big deal about hovering your mouse over the variable for a second and just seeing what type is it? Much better than running to the declaration anyway.

2018年09月25日58分40秒

Generic variable and function names (variable, CallMe) make bad examples. However, if CallMe() was a function in some kind of a "phone application", then var call = CallMe(); .... call.HangUp(); would make much more sense.

2018年09月25日58分40秒

Randolpho: "what's the big deal about hovering your mouse over the variable for a second and just seeing what type is it?" It adds time to the maintenance overhead... plus one second is only the hover time rather than counting the keyboard to mouse context switch. I don't know about you, but I work with a deadline. Every time I have to hover over a variable to find out what type it is, is time that I could have better spent fixing a problem.

2018年09月25日58分40秒

+1, only person to note that var has nothing to do with Variant.

2018年09月25日58分40秒

(for info, you can get similar issues on anything where this is an implicit type conversion)

2018年09月26日58分40秒

Disagree with the part that you don't want to see it twice in the same line. It is possible that in the future you are not directly creating the variable after declaring (for example in an if below the definition) than it might not directly be clear what the type is. Most developers are used to see the type directly at the beginning of the line especially in complex code you don't want to make reading the code more difficult.

2018年09月25日58分40秒

TheVillageIdiot - I rolled back your edit, because on this occasion the hscroll is related to the point ;-p

2018年09月26日58分40秒

Gertjan - my brain is limited; if it is complex, I don't want to see it twice and have to start comparing (interface/concrete/etc). I'm happy to see it once and think "typed as one of them".

2018年09月26日58分40秒

Why the heck are you code reviewing on paper? Think of the trees! ;)

2018年09月25日58分40秒

You can have the same problem without using var. The problem isn't var; the problem is bad variable names. If variable names are well-chosen, the use of var doesn't matter.

2018年09月25日58分40秒

I have a guy on my team that reviews his own code, and looks for bugs, by printing his code. His walls are COVERED with code. I once walked in and he had an entire large whiteboard covered with a single of his debugging exercises. It was probably ~10000 LOC

2018年09月25日58分40秒

LuckyLindy, wow, that's too much, I think.

2018年09月25日58分40秒

Variable names alone don't solve the problem unless you go back to hungarian notation where the type is part of the name.

2018年09月25日58分40秒

the type of 'something' is very clear to the compiler, internally, the "var" gets set to the return type of 'someMethod', it is clear to the compiler, but may not be clear to the developers working on the project. and Boo is growing on me quickly.

2018年09月25日58分40秒

No, v = List<somethinglongtypename>(); is not even nicer. It is important to distinguish between introducing a new variable and assigning to an existing variable.

2018年09月25日58分40秒

Well if you have assigned to 'v' before in the current scope, then it's assignment to an existing. Otherwise it's assignment to new variable 'v'. Easy.

2018年09月25日58分40秒

I didn't actually consider this, at it seems from the other question that is a fairly strong point for one other time to use it.

2018年09月25日58分40秒

That was basically the only reason they implemented it (besides being able to declare anonymous types, but they could have made "var" a special keyword that was only for anonymous types.)

2018年09月26日58分40秒

+1 for this. int versus var is something to bicker about, but multiple nested generic types make var a godsend. This is where using the type name over and over really destroys the readability of code.

2018年09月25日58分40秒

This is absolutely the wrong reason for using it. If your code uses a nested generic type you should derive a specific named class for it. For example: class IntStringEnumerator : IEnumerable<MyStupidLongNamedGenericClass<int, string>> and then use the new name. That cleans up the code and describes the type better.

2018年09月26日58分40秒

Alright, but my example was just hyperbole. IntStringEnumerator i = new IntStringEnumerator() is still too much typing.

2018年09月25日58分40秒

Your examples above aren't an argument for not using var; they're an argument for using good descriptive variable names. If, instead of [var fc = Factory.Run();] you had [bool fc = Factory.Run();], the code wouldn't become any clearer.

2018年09月26日58分40秒

agreed - wondering why this nice side effect isn't being touted as much as some of the other, more subjective pros in the more popular responses.

2018年09月25日58分40秒

It hapen to me today. I have a factory class that return istance of a MainMenu class. Today i created a MainMenu2 with the same interface of MainMenu. I have my all app code untouched after the change!

2018年09月25日58分40秒

It's interesting you say that because var can make refactoring simpler. If you've used var you don't have to. Now you can always rely on the IDE's refactoring tools, but you know, you can always rely on the IDE for the type as well :)

2018年09月25日58分40秒

Please rid off IQueriable<T> before iterating: anonEnumeration.ToList();

2018年09月25日58分40秒

DavidDiez could you rephrase? Your statement makes no sense. None of my code snippets reference IQueryable or .ToList()

2018年09月25日58分40秒

var anonEnumeration = from post in AllPosts() where post.Date > oldDate let author = GetAuthor( post.AuthorId ) select new { PostName = post.Name, post.Date, AuthorName = author.Name }; does not return an IQueriable<T>?

2018年09月25日58分40秒

DavidDiez it depends on what AllPosts() returns - the asker refers to List<T> so I assumed that. In that case the result is that anonEnumeration will be of type IEnumerable<'a>. Now if AllPosts() returns IQueryable<T> instead then anonEnumeration will become IQueryable<'a> (note no i in Queryable) - however in that case my code still works because IQueryable<T> implements IEnumerable<T>. There are loads of better Q&As on here about the distinctions between them - here my case is that 'a is anonymous and var allows you to assign it to a statically typed variable.

2018年09月25日58分40秒

Ohh I see, thanks for explaining it :) My comment was because iterating an IQueryable<T> is not a good practice because in each iteration you are making a read statement in DB. Be sure to *.ToList() IQueryable<T>'s before iterating them

2018年09月25日58分40秒

Presumably in .Net 4 where dynamic types are common place, this will become more important?

2018年09月26日58分40秒

On the contrary, if you're confused by "var" now, I would expect that you will be additionally confused by "dynamic." God forbid anyone ever declares a dynamic and then makes a reference to it using "var" :)

2018年09月26日58分40秒

I meant something like dynamic d = 52; var x = d; which ought to be fine.

2018年09月25日58分40秒

If the right hand side isn't clear enough to justify the use of var, then var isn't the problem: the right hand side is the problem. It's not descriptive enough. Customer c = GetContext() is still unclear and no better than using var.

2018年09月26日58分40秒

Funny you mention bilingualism as something that promotes the use of var. My antagonism towards the var keyword stems directly from my fluency in javascript! :)

2018年09月26日58分40秒

var in C# has no connection whatsoever with var in JavaScript. A var-declared variable in C# is strongly-typed.

2018年09月25日58分40秒

Wow. Ignoring all the arguments brought forth in this thread so far and re-setting the whole discussion is quite an achievement.

2018年09月25日58分40秒

This 100% describes how I feel about 'var', particularly from the standpoint of picking up someone elses code. Use of var radically changes the task at hand if it's littered throughout. +1

2018年09月26日58分40秒

I find the repetition of stringBuilder sb = new StringBuilder() messy and longer to clearly recognise. It's extra noise. The problem is, determining what does and doesn't constitute extra intellectual effort to understand some code is pretty subjective!

2018年09月25日58分40秒

"var should never be used except where the type is not known..." - You can ALWAYS know the type, as does the compiler. This is not dynamic typing, it just lets the compiler determine the type for you. But the type is never an unknown.

2018年09月26日58分40秒

Yup, compilers are smarter than us, get over it!

2018年09月25日58分40秒