|
Utwig wrote: The article is simply wrong.
Ohh, really? Can you please be specific on your concerns?
Utwig wrote: Boxing\un-boxing argumentation is wrong.
I have been addressing this issue here in this comment "http://www.codeproject.com/Messages/3260191/Boxing-and-implicit-typing.aspx". I request you to go through my responses on this thread and then put specific comments, in case your understanding does not get mature.
Utwig wrote: Using "var customer = new Customer()" is a recommended practice from MS developers. See also
http://stackoverflow.com/questions/209199/whats-the-point-of-the-var-keyword/209261#209261
I can just lough, it seems you are in a mission to make such comments. You did not even properly read my article nor understood the stackoverflow article.
Here is was stackoverflow says:
"...instead of
SomeGeneric<VeryLongTypename<NestedTypename>> thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();<br /> , consider
var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();<br /> ..."
Which is pretty much the same, that I wrote :
1. Do use ‘var’ to:... c.Refer complex generic types.
What are you talking about then?
|
|
|
|
|
Utwig,
I would agree with you if you argued that "var customer = new Customer()" is good practice.
But you also need to argument correctly, considering the essence of the topic instead of just referring to some "authorities".
Sergey A Kryukov
|
|
|
|
|
The implicitly typed 'var' is just a compiler trick that makes life easier for us developers. C# 3.0 was released with no new CLR so nothing changed under the hood.
There has been some discussion around
int i = 2; vs. var i = 2;
they are the same thing.
here is some code that i slaved over for your consideration
private static void CreateImplicitInteger()
{
var i = 2;
}
private static void CreateExplicitInteger()
{
int i = 2;
}
the 2 methods produce the same IL:
.method private hidebysig static void CreateImplicitInteger() cil managed
{
.maxstack 1
.locals init ([0] int32 i)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ret
}
and
.method private hidebysig static void CreateExplicitInteger() cil managed
{
.maxstack 1
.locals init ([0] int32 i)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: ret
}
Also, i would disagree with the author and encourage people to use var like so:
var customer = new Customer();
This can really save you time and effort when refactoring.
Let's say that i decide to create a CustomerBase class ot inherit form and then decide to new up my Customer as a CustomerBase.
If I use Implicit typing then I change my code in 1 place.
var customer = new Customer();
If I use Explicit typing then I change my code in 2 places.
Customer customer = new Customer();
|
|
|
|
|
I did not really understood what you different thing you meant in the comment reg. the int example.
I have mentioned "int i = 2 can now be written as var i = 2, without having to worry about the overhead for boxing/un-boxing." which 100% the fact! Can you disagree?
Now if you have concern on bringing in the 'boxing/un-boxing' context, in the sentence, I can address that. If you have any other concern please be specific.
The reason behind bringing in the 'boxing/un-boxing' context is that, previously implicit typing (or to be more specific, using a common type to store any type instance) was done using boxing (for the primitive types). Therefore, even if developers wanted to use implicit types it was not possible without having to compromise the performance. So, it made sense for me, to mention that now with 3.0 implicit typing is possible without the cost, since 'var' was introduced without a new CLR version! !
Now coming to the 'customer' example: if you really want to save time on such refactoring use Visual studio refactoring features. Living in this age if you want to manually change the code to do such refactoring, I can not agree with you.
Now leaving the refactoring issue apart, on the code, as a common tendency we look at the left-side of a variable declaration to know its type.(Any programming language, you take, follows this notation.) Now if you suggesting that, it’s better to look at the right to know the type. It is your own choice. But when the readability is concerned I feel its better to follow the usual notations.
modified on Thursday, November 5, 2009 4:08 AM
|
|
|
|
|
I can disagree with your statement 'int i = 2 can now be written as var i = 2, without having to worry about the overhead for boxing/un-boxing'.
I am not sure why you are stuck on the boxing/unboxing. since the implicit veriable 'var' is just a compiler trick, there is no difference between the IL code that it prodcudes. Therefore any boxing/unboxing operations don't change.
consider these 2 methods:
private static void BoxingUnboxingWithVar()
{
var i = 123;
object o = i;
var j = (int)o;
}
private static void BoxingUnboxingWithoutVar()
{
int i = 123;
object o = i;
int j = (int)o;
}
the IL code that they produce is exactly the same:
.method private hidebysig static void BoxingUnboxingWithVar() cil managed
{
.maxstack 1
.locals init ([0] int32 i,
[1] object o,
[2] int32 j)
IL_0000: nop
IL_0001: ldc.i4.s 123
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: box [mscorlib]System.Int32
IL_000a: stloc.1
IL_000b: ldloc.1
IL_000c: unbox.any [mscorlib]System.Int32
IL_0011: stloc.2
IL_0012: ret
}
.method private hidebysig static void BoxingUnboxingWithoutVar() cil managed
{
.maxstack 1
.locals init ([0] int32 i,
[1] object o,
[2] int32 j)
IL_0000: nop
IL_0001: ldc.i4.s 123
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: box [mscorlib]System.Int32
IL_000a: stloc.1
IL_000b: ldloc.1
IL_000c: unbox.any [mscorlib]System.Int32
IL_0011: stloc.2
IL_0012: ret
}
as you can see the IL code is the same, so you are misinforming people when you say that boxing/unboxing operations are different when using var.
ATANU.PODDER wrote: Now coming to the 'customer' example: if you really want to save time on such refactoring use Visual studio refactoring features. Living in this age if you want to manually change the code to do such refactoring, I can not agree with you.
the Customer example i gave cannot be helped with VS refactoring tools or ReSharper, which i prefer over VS refacotring.
ATANU.PODDER wrote: as a common tendency we look at the left-side of a variable declaration to know its type.(Any programming language, you take, follows this notation.) Now if you suggesting that, it’s better to look at the right to know the type. It is your own choice. But when the readability is concerned I feel its better to follow the usual notations.
i do agree with you here, but i don't feel that:
Customer cust = new Customer();
is much more readable than:
var cust = new Customer();
|
|
|
|
|
You have not understood what I intended on that statement, read it again
ATANU.PODDER wrote: With the arrival of ‘var’ in C# 3.0, it now allows a developer to write more relaxed code.
int i = 2 can now be written as var i = 2, without having to worry about the overhead for boxing/un-boxing.
What I meant is, previously using a common type to store any type instance was done using boxing (for the primitive types). Therefore, even if developers wanted to write such code s it was not possible without having to compromise the performance. So, it made sense for me, to mention that now with 3.0 implicit typing is possible without the cost, since 'var' was introduced without a new CLR version!!!
I have not suggested that boxing and un-boxing operations are different when using var. That is your interpretation, which needs a correction.
PCoffey wrote: the Customer example i gave cannot be helped with VS refactoring tools or ReSharper, which i prefer over VS refacotring.
In that example, you just basically trying to rename the 'Customer' class to 'CustomerBase'. You neither need Resharper nor need to do that manually. Here is how you can do that with VS, after you rename the class, press 'Shift-Alt-F10', you will get a menu which says 'Rename Customer to CustomerBase', just click that. You are all done! There is rename with preview option also there.
PCoffey wrote: i do agree with you here, but i don't feel that:
Customer cust = new Customer();
is much more readable than:
var cust = new Customer();
Thanks for agreeing, now even after agreeing you do not feel to accept the readability, that is up to you.
|
|
|
|
|
I am only reading the posts, but I must say that the rename is not an option...
If I understood well, the example is:
Use another class instead of customer. If the declaration is
Customer customer = new Customer();
You will have to change 2 places.
And, as I also mentioned, I think using var when the type is obvious is not a problem.
I don't read "the left" to see what is the type. The color of the class is different, and the variable also says what it is. So, using var is not a problem.
|
|
|
|
|
Paulo Zemek wrote: If I understood well, the example is:
Use another class instead of customer. If the declaration is
Customer customer = new Customer();
You will have to change 2 places.
You have not understood this well! Its not about creating a new class. If you create a new class called 'CustomerBase' then how will it know any thing about the derived class 'Customer'? Then all the code you have written in that context will have to change, and that's probably not re-factoring !!!
Is it clear now?
Paulo Zemek wrote: And, as I also mentioned, I think using var when the type is obvious is not a problem.
I don't read "the left" to see what is the type. The color of the class is different, and the variable also says what it is. So, using var is not a problem.
You look at the color to see the type, is fine. But you look at the color in which side of the variable declaration, left or right? That is my question. A common tendency is to look at left side, and that is what I meant to mention.
|
|
|
|
|
No, I don't look left. I can see more than one word at the same time.
If I am looking for something I will probably be already seeing many lines at the same time, searching for "something" that gives me the feeling "it's here".
But I don't think this discussion should continue.
|
|
|
|
|
Aaaaha...you are cutting corners. I just have one advice for you, if you want to say something, be more specific, than being abstract.
Paulo Zemek wrote: No, I don't look left. I can see more than one word at the same time.
See here, I can still ask you, what would be more easy reading habit reading left to right or otherwise?
|
|
|
|
|
Well... when I program, I look for { and }, for the identation, colors... and, of course, when reading, left to right.
I was not trying to make a war (as it may look), I was only saying that var customer = new Customer(), for me, is not less readable, because:
I will probably not be reading line by line, I will be looking for something (like the identantion and the color of the variable).
I will read from left to right, but my brain does not read only one word at a time. So, var X, in my brain, will be var X. Not var and, after, X.
And, if the problem is the left to right, I must say that var dictionary = new Dictionary<myverylongtypeaskey, keyvaluepair<otherverylongtype,="" andyetanotherverylongtype="">> will also need to be
Dictionary<MyVeryLongTypeAsKey, KeyValuePair<OtherVeryLongType, AndYetAnotherVeryLongType>> dictionary = new Dictionary<MyVeryLongTypeAsKey, KeyValuePair<OtherVeryLongType, AndYetAnotherVeryLongType>>
as when reading from left to right, the "var" will be a problem. But, not only writing such thing is terrible and the type is obviously there, the real problem will not be "finding" the class declaration, but discovering what it really means.
So, as I said, the problem is that item in particular.
I do not need to read X x = new X() to understand that we are talking about x.
I also do not need to read MyVeryLongClass myVeryLongClass = new VeryLongClass() to understand we are talking about MyVeryLongClass.
But, to be honest, I always though such feature must work in the reverse way. Instead of
var class = new Class()
I always though of something like:
Class class = new();
So, when the "type" is missing, the new will be automatically "Class". But, of course, this will help solve this discussion, but will not allow for unnamed types to be created.
modified on Saturday, November 7, 2009 9:31 PM
|
|
|
|
|
Paulo Zemek wrote: But, to be honest, I always though such feature must work in the reverse way. Instead of
var class = new Class()
I always though of something like:
Class class = new();
So, when the "type" is missing, the new will be automatically "Class". But, of course, this will help solve this discussion, but will not allow for unnamed types to be created.
Agreed.
|
|
|
|
|
... is correct. Anyway, the article itself is poor because of formatting, explanations and proofs (by concept).
|
|
|
|
|
I'm sorry but I'm almost positive that this:
"int i = 2 can now be written as var i = 2, without having to worry about the overhead for boxing/un-boxing."
is completely false, and has nothing to do with why var was added to the language.
I see the formatting is fixed, I wonder why the comments weren't answered.
|
|
|
|
|
Yes, of course. (Un-)boxing has nothing to do with the variant keyword. I did not mention that because someone already did it.
|
|
|
|
|
Of course the article is unacceptably incorrect and lack proper proof and motivation, but you still should follow formal logic in your arguments.
Yes, this statement is formally correct; and you actually confirm this by saying that "var" has nothing to do with boxing/unboxing.
This is exactly the reason why it "can be written... without having to worry about the overhead for boxing/un-boxing".
From the other hand, this part of the statement related to boxing is completely pointless and misleading.
I don't even want to argue with author's arguments on why boxing was even mentioned -- others said enough; it looks like retrospective attempts of the author to cover his mistake.
Sergey A Kryukov
|
|
|
|
|
To respond to the first comment of 'Alexander Müller'
Can you be more specific than being abstract. What did you intend to convey when you mentioned "the article itself is poor because of...explanations and proofs (by concept)."
Reg. the issue of poor formatting, I have done the formatting based on my understanding of the editor and its tags. The text editor can be improved to incorporate a WYSIWYG based approach.
To respond to the comment of 'dequadin'
I think you misunderstood the intention of the statement "int i = 2 can now be written as var i = 2, without having to worry about the overhead for boxing/un-boxing."
My intention here is not to describe why was 'var' introduced. Rather, what I intended was, if developers wanted to store different type instances with a common type, its now easy with var. And there is no cost, unlike boxing!
To answer to your query on delayed response, I am currently in different timezone than yours.
To respond to the second comment of 'Alexander Müller'
Just to bring the context of, using a common type to store different types, I have mentioned boxing.
Ask a developer, at the first glance, when the 'var' was introduced to one, is not it sounded similar to 'object'? Its only when finished reading about var, the developer understood its different.
The intention was to start with something which is easy to relate to and then explain the difference.
modified on Thursday, November 5, 2009 4:11 AM
|
|
|
|
|
What I did intend to convey is that - from a scientific point of view - important things are missing, i.e. the "why X?" is never answered.
For example:
Why should one use var customer = new Customer(); instead of Customer customer = new Customer(); ? Someone may claim that customer is self-explanatory. Smalltalk ppl would also claim that type inference is awesome because it makes rapid prototyping more rapid. By some means or other they are right because you can decrease redundancy...
|
|
|
|
|
The intention of the article is to consolidate a best practice of using or not using 'var'. Now, first 7-8 line of the articles talks about the reason and explanation. Point to note here is that, using var instead of an explicit type does not have any serious impact like performance etc. Only thing it impacts is readability. And I have mentioned it in the beginning only. I am still not able to understand what was it "poor because of ... explanations and proofs (by concept). " to you.
Now to answer to your example
"Why should one use var customer = new Customer(); instead of Customer customer = new Customer();?"
Below is my response, an excerpt from the article itself
"... it is not always the best thing to use var. While using ‘var’ can help developers to avoid all the type declarations for local variables, it has impact on code readability.
...
Consider code readability and maintainability while making a choice between ‘var’ and explicit type. "
Now if the question here is to debate between "var customer = new Customer();" with "Customer customer = new Customer();", which is more readable. For me it makes sense to suggest something, which is more common and have a wide acceptance. Its so obvious to look at the left of a variable declaration to know its type. Isn't it?
|
|
|
|
|
Choosing whether to use var or not is not only a question of readability and maintainability. Even (compiling, not runtime) performance is a problem because the time is in worst-case exponential [1].
[1] J. Palsberg and M.I. Schwartzbach, "Object-Oriented Type Inference," Proc. ACM Conf. Object-Oriented Programming: Systems, Languages and Applications, pp. 146-161, Phoenix, AZ, Oct. 1991.
|
|
|
|
|
You mean theoretically, right?
Otherwise its compiling performance penalty limit to zero. This is subtle, when making a suggestion towards best practice, I feel.
Additionally how much importance compiling performance penalty has to this article, you think?
|
|
|
|
|
Best practise is mainly important in enterprise systems. These systems tend to consist of millions of lines of code. Ask someone at e.g. SAP how long it takes to compile an application. Some will answer "1 to 7 days". If you can avoid 1-12 hours, why not?
Best practise is always best practise and not only for small systems.
|
|
|
|
|
There is never a best practice that suits all. One size does not fit everyone. That is why there is a term named 'Tailoring'.
When we make a general suggestion on best practice, we usually take account of the common, and not the exceptions.
For e.g. FxCop makes a general suggestion 'Do not catch generic exception types' but there are many occurrences where we are bound to do that (for whatever reasons).
Further, you believe changing implicit to explicit typing would save that 4% - 7% percentage build time. That is far from reality. Try it your self, compiling 10000 line of code declaring variables explicitly vs 10000 lines of code declaring variables implicitly. Its not even in two decimal fraction. What impact are you talking about then?
|
|
|
|
|
Please cite your source as to how implicit typing has anything to do with boxing/unboxing? Boxing/Unboxing has everything to do with treating value types as reference types.
int i = 0; // <- no boxing here?
var i = 0; // <- no boxing here either
|
|
|
|
|
I think I have addressed this issue in the other response. Anyways, the reason behind bringing in the 'boxing/un-boxing' context is that, previously implicit typing (or to be more specific, using a common type to store any type instance) was done using boxing. Therefore, even if developers wanted to use implicit types it was not possible without having to compromise the performance. So, it made sense for me, to mention that now with 3.0 implicit typing is possible without the cost since 'var' was introduced without a new CLR version!!
modified on Thursday, November 5, 2009 4:12 AM
|
|
|
|
|