Are people abusing "var"?

  • Thread starter Thread starter Jeff Johnson
  • Start date Start date
J

Jeff Johnson

I've barely touched VS 2008 because not everyone in my organization has it,
so I may not know enough to form this opinion, but I've seen lots of code
samples in this group where people are using the new var keyword in places
it seems very appropriate (i.e., lazy). For those of you who are immersed in
the 3.x Framework, do you think people are misusing this keyword? Or do you
recommend its use whenever possible?
 
Jeff Johnson said:
I've barely touched VS 2008 because not everyone in my organization has
it, so I may not know enough to form this opinion, but I've seen lots of
code samples in this group where people are using the new var keyword in
places it seems very
INappropriate

(i.e., lazy). For those of you who are immersed in the 3.x Framework, do
you think people are misusing this keyword? Or do you recommend its use
whenever possible?


(Argh.)
 
I'm not too immersed in the whole thing but I suspect some people will
really abuse the var keyword instead. My 2 cents is that its better to
declare variables with the right type where possible instead of
scattering var's all over the place. After all you might come back to
your code a few projects later and certainly don't want to figure out
what all those variables of type var do really hold.
 
My 2 cents is that its better to
declare variables with the right type where possible instead of
scattering var's all over the place.

Which is my gut feeling as well.
 
Frank,

I agree with most, that var should not be used when you know the type
you are working with. I trust the type inference, actually, but it's more
about the readability of the code for me.
 
Actually, you never have to figure out the type later - the IDE intellisense
will display the implied type when you hover over the 'var' or over the
variable reference (just as if you had declared the type explicitly) - type
inference works at compile time, not runtime.

That said, I find it very annoying to see 'var' used for trivial cases like
"var i = 2". This just displays a lack of common sense.
--
http://www.tangiblesoftwaresolutions.com
C++ to C#
C++ to VB
C++ to Java
VB & C# to Java
Java to VB & C#
Instant C#: VB to C#
Instant VB: C# to VB
Instant C++: VB, C#, or Java to C++/CLI
 
Even though C# makes a reasonable stab at choosing the most
appropriate datatype
(http://msdn.microsoft.com/en-us/library/bb384061.aspx), I prefer to
tell it what I mean explicitly rather than allow it to decide what it
thinks I mean implicitly...

Absolutely. This is one of the reasons that I choose to use statically
typed languages at all: not using some mechanism like "var" eliminates
many classes of code by specifying _precisely_ what you want. While
"var" is easily figured out by the computer, it's far easier for a
human to see "int" or "string" or even "object", if it must be.

--- Mike
 
Mark Rae said:
I fully agree. Smacks too much of "Dim var As Variant" to me...

Even though C# makes a reasonable stab at choosing the most appropriate
datatype (http://msdn.microsoft.com/en-us/library/bb384061.aspx), I prefer
to tell it what I mean explicitly rather than allow it to decide what it
thinks I mean implicitly...

C# doesn't just make a "reasonable stab" at choosing the type, it
deterimines clearly and definitively what the type to attach to the
identifier. The rule is very simple, the type choosen is the type of the
expression on the RHS of the assignment.

For the sake of balance consider this:-

MyClassWithALongName thing = new MyClassWithALongName();

compared to:-

var thing = new MyClassWithALongName();

There are places in code where we have 'Tramp' data, that is values held
that are 'just passing through'. In these cases var is helpful, e.g.;

A set of static methods in a library currently being developed:-

fnA() returns type X
fnB(X p) takes a parameter of type X
fnC(X p) also takes a parameter of type X

In tandem we have code that consumes the library currently looks like this:-

X a = Library.fnA();
Library.fnB(a);
Library.fnC(a);

Now the developer of the library decides that fnA should return Y and fnB,
fnC accept Y. The consumer code is now broken. However if the consumer
used var instead of X, it would no longer care whether X or Y is in use, its
not bothered by it and things continue to work as expected.

Generally I agree though just using var because you can is a bad idea, it
needs to be a considered choice where the circumstance warrants it. If it
weren't for anonymous types I don't think the language designers would have
added var.

If you think var is open to abuse just wait and see what happens when
developers get hold of dynamic in C# 4. That's equivalent to Dim x as
Object in VB6. Yikes!
 
A set of static methods in a library currently being developed:-

fnA() returns type X
fnB(X p) takes a parameter of type X
fnC(X p) also takes a parameter of type X

In tandem we have code that consumes the library currently looks like
this:-

X a = Library.fnA();
Library.fnB(a);
Library.fnC(a);

Now the developer of the library decides that fnA should return Y and
fnB, fnC accept Y. The consumer code is now broken. However if the
consumer used var instead of X, it would no longer care whether X or
Y is in use, its not bothered by it and things continue to work as
expected.

AIUI, this would still be an ABI-breaking change, would it not? Isn't
"var" resolved at compile-time, or is it resolved at run-time?

--- Mike
 
If you think var is open to abuse just wait and see what happens when
developers get hold of dynamic in C# 4. That's equivalent to Dim x as
Object in VB6. Yikes!

And how is Dim x As Object so horrible compared to object x in C#...?
 
Jeff Johnson said:
I've barely touched VS 2008 because not everyone in my organization has
it, so I may not know enough to form this opinion, but I've seen lots of
code samples in this group where people are using the new var keyword in
places it seems very appropriate (i.e., lazy). For those of you who are
immersed in the 3.x Framework, do you think people are misusing this
keyword? Or do you recommend its use whenever possible?

IMO, the reason this often happens isn't purposeful on the part of the
programmer. For example, in Rattz's Linq book, he recommends using var
until you can figure out what type you're dealing with. This advice is fine
as far as it goes, but you know what happens... you try something, you get
it to work, and then you forget to go back and make it more explicit later
when you understand it better. I doubt many people intentionally use var
even when they know the types they're dealing with, but I could be wrong.
Maybe it's just their misunderstanding from seeing so many other examples of
code, that you're supposed to do it that way.
 
I fully agree. Smacks too much of "Dim var As Variant" to me...

Just to be clear, the var keyword in csharp is not equivalent to a
Variant in VB6.

With a variant, the following code is ok:

Dim var As Variant = "Hello" 'Variant with string data
var = 1234 'Variant now holds integer data


The var keyword in C# does not allow this:

var v = "Hello"; //v is a string variable
v = 1234; //compile error!

I just wanted to make sure that anyone new to type inference in C# was
aware of this.

Chris
 
Jeff said:
And how is Dim x As Object so horrible compared to object x in C#...?

Because

x.SomeNonExistantMethod()

is rejected at compile-time by C# and at runtime by VB6.
 
Jeff Johnson said:
And how is Dim x As Object so horrible compared to object x in C#...?

Because in VB6:-

Sub DoStuff(ByVal x as Object)
x.DoMethodOfThing 'Will fail at runtime if object referenced by x does
not have a DoMethodOfThing
End Sub
....
Dim y as Object
Set y = new NotAThing()
DoStuff y ' Oops but only at runtime.



Whereas in C# 3 and below :-

void DoStuff(object x)
{
x.DoMethodOfThing(); //Fails to compile object does not have
DoMethodOfThing.
}
....
object y = new NotAThing();
DoStuff(y); // We do not need to wait until this code runs to see we have
problem.


Where in VB6 methods and properties can be access dynamically via the Object
type in C# only the few methods and properties (such as GetType()) defined
for the Object datatype itself can be used.


In C#4 the same runtime issue we have with Object in VB6 can be had:-


void DoStuff(dynamic x)
{
x.DoMethodOfThing(); //Compiles fine, DoMethodOfThing is lookup
dynamically at runtime.
}
....
object y = new NotAThing();
DoStuff(y); // Oops this fails but only when the code gets run this far.


I can see developers not well informed using this as an easy shortcut.
 
Michael B. Trausch said:
AIUI, this would still be an ABI-breaking change, would it not?

I'm not sure I understand what ABI-breaking change is.

I wasn't suggesting that compiled code would be happy with a library
changing in this way, it won't. However as a solution evolves
incremenatally using var may reduce the number of point s that need
refactoring when such a change takes place.
Isn't "var" resolved at compile-time, or is it resolved at run-time?

Its resolved at compile time.
 
Generally I agree though just using var because you can is a bad idea, it
needs to be a considered choice where the circumstance warrants it. If it
weren't for anonymous types I don't think the language designers would
have added var.

If it was added for just anonymous types, they could have made it work only
where the RH side was anonymous...and then the keyword could have been
"anon" instead of "var". Thereby making sure it's anonymous type reference
only. But alas, I think it's deeper than that. I think there is more
reason than just anonymous types that they added the "var"
implementation....(and yeah, var does NOT mean variant as in VB's
implementation of variant....).

HTH,
Mythran
 
David Anton said:
Actually, you never have to figure out the type later - the IDE
intellisense
will display the implied type when you hover over the 'var' or over the
variable reference (just as if you had declared the type explicitly) -
type
inference works at compile time, not runtime.
</snip>

Umm, I would LOVE to see how that works when you send that code to a
printer....too bad we can't mouse over the variables on a sheet of 8½" x 11"
paper! :) So, to say "you never have to figure out the type later" is a
little off....specially when you want to print code to the printer for some
reason (I've done it, although I 999 times out of 1000 I don't print code).

Mythran
 
Mythran said:
If it was added for just anonymous types, they could have made it work
only where the RH side was anonymous...and then the keyword could have
been "anon" instead of "var". Thereby making sure it's anonymous type
reference only. But alas, I think it's deeper than that. I think there
is more reason than just anonymous types that they added the "var"
implementation....(and yeah, var does NOT mean variant as in VB's
implementation of variant....).

Nope I think anonymous types is pretty much it. They've allowed var to be
used in other circumstances because it can be useful and convienant at times
and doing so wasn't costing them anything because its necessary for
anonymous types, which in turn are necessary for LINQ. If it weren't for
anonymous types I don't think the other uses of var (bearing in mind its
downsides as far a code clarity is concerned) would warrant its inclusion.
 
MC said:
Michael B. Trausch said:
Absolutely. This is one of the reasons that I choose to use statically
typed languages at all: not using some mechanism like "var" eliminates
many classes of code by specifying _precisely_ what you want. While
"var" is easily figured out by the computer, it's far easier for a
human to see "int" or "string" or even "object", if it must be.

[ "many classes of code" => "many classes of coding errors" ? ]

Right! By declaring types, you make sure the compiler knows what YOU are
thinking, so if you make a mistake later on, you'll be warned!

This was one of the key insights in the original design of Pascal (which,
despite superficial differences, is an important intellectual ancestor of
C#): Let the compiler help you keep >track of what YOU think the data
types and structures should be.

But this is not an issue with auto.

Var doesn't mean variant, and the object is still strongly typed. If the
compiler can deduce what you mean without any ambiguity, why should you
still need to say it ?

Another thing to consider is that var can only be used locally. So, if the
reader has a problem to understand what is the real type of the object
(let's suppose the intellisens won't tell him), i guess there is something
very wrong either with the function, either with the reader.

And because the object will be very local, to know preciseley what is the
type of the object will be useless most of the time, as long as the compiler
can do its type checking.
 
Anthony Jones said:
Nope I think anonymous types is pretty much it. They've allowed var to be
used in other circumstances because it can be useful and convienant at
times and doing so wasn't costing them anything because its necessary for
anonymous types, which in turn are necessary for LINQ. If it weren't for
anonymous types I don't think the other uses of var (bearing in mind its
downsides as far a code clarity is concerned) would warrant its inclusion.

Var is also useful when dealing with generics, which is why it should be
soon a feature of c++.
 
Back
Top