c# v3.0: implicit variable declaration, why?

  • Thread starter Thread starter Nathan Laff
  • Start date Start date
N

Nathan Laff

so, myself and the other developers i work with were looking at the v3.0
specifications. extensions look great, buy what is the point of implicit
variables with the 'var' type?

before you bash me too much, keep in mind, we're a delphi shop, moving to c#
so we've not been in there too much yet, but this seems to be kind of
pointless. if you have to initialize when you declare, why not just type it
for readability sake?

we watched the video on msdn, but still don't quite get it...

can someone give me a real world example of where this is useful?
 
Nathan,

It's a reasonable question. The short answer is that it is just one
part in a much larger set of features that are offered with C# 3.0. Now
onto the long answer.

So, with implicit variables you can certainly do this:

var i = 10; // int
var s = "hello"; // string

And if I ever saw someone working for me do that, then I would fire them
(maybe not in the case of really long parameterized/Generic types, but a
"using" directive works just as well).

However, in C# 3.0, you can create anonymous types, like this:

var x = new {Prop1 = "Hello", Prop2 = 10};

The syntax might be off here, but you should get the general idea. Now,
when you do this, the compiler is creating a type with a Prop1 property and
a Prop2 property, with a very specific type signature. However, at
code-time, you don't have access to that type, which is what the var is for.

The great thing is that once you do that, you can't change the type of
var, it is definitely typed. So it is type safe. You can only assign an
instance of another type.

Now, this feature in itself is great, IMO, but that's not all of it.
This is actually what is used to implement projections in LINQ. Now that
you can do anonymous types like this, you can pick and choose what
properties you want to return from your queries.

This of course results in a return value from your queries of
IEnumerable<anonymous type> where "anonymous type" contains the properties
you selected in your query to return.

Hope this helps.
 
"Nathan Laff" <[email protected]> a écrit dans le message de (e-mail address removed)...

| so, myself and the other developers i work with were looking at the v3.0
| specifications. extensions look great, buy what is the point of implicit
| variables with the 'var' type?
|
| before you bash me too much, keep in mind, we're a delphi shop, moving to
c#
| so we've not been in there too much yet, but this seems to be kind of
| pointless. if you have to initialize when you declare, why not just type
it
| for readability sake?

Implicit variables are a bit like class helpers, they are there, primarily,
to provide facility for framework functionality.

The main reason for implicit variables is to allow for things like Linq
where a code "query" against a list of objects or a database can return
strongly typed results into variables declared in the query.

{
var result = from c in Customers
where c.ContactTitle.Length == 5
select c.ContactName;
}

This example will select the single string property ContactName where the
length of the ContactTitle property is 5 characters, from a list of Customer
objects. The compiler knows that the property is a string and therefore
makes the var type to be string.

Note that this is nothing to do with variants; var declarations are strongly
typed on their first assignment and remain that type from then on. They
cannot change type.

{
var result = from c in Customers
where c.ContactTitle.Length == 5
select c.ContactName, c.Age, c.CurrentBalance;
}

This kind of query will return a class with three members, one for each
property in the select statement of the query. Something like :

class Result
{
string ContactName;
int Age;
decimal CurrentBalance;
}

Joanna
 
Seems to me that we're going backwards on this.... towards
JavaScript/VBScript == Bad?


Nicholas Paldino said:
Nathan,

It's a reasonable question. The short answer is that it is just one
part in a much larger set of features that are offered with C# 3.0. Now
onto the long answer.

So, with implicit variables you can certainly do this:

var i = 10; // int
var s = "hello"; // string

And if I ever saw someone working for me do that, then I would fire
them (maybe not in the case of really long parameterized/Generic types,
but a "using" directive works just as well).

However, in C# 3.0, you can create anonymous types, like this:

var x = new {Prop1 = "Hello", Prop2 = 10};

The syntax might be off here, but you should get the general idea.
Now, when you do this, the compiler is creating a type with a Prop1
property and a Prop2 property, with a very specific type signature.
However, at code-time, you don't have access to that type, which is what
the var is for.

The great thing is that once you do that, you can't change the type of
var, it is definitely typed. So it is type safe. You can only assign an
instance of another type.

Now, this feature in itself is great, IMO, but that's not all of it.
This is actually what is used to implement projections in LINQ. Now that
you can do anonymous types like this, you can pick and choose what
properties you want to return from your queries.

This of course results in a return value from your queries of
IEnumerable<anonymous type> where "anonymous type" contains the properties
you selected in your query to return.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Nathan Laff said:
so, myself and the other developers i work with were looking at the v3.0
specifications. extensions look great, buy what is the point of implicit
variables with the 'var' type?

before you bash me too much, keep in mind, we're a delphi shop, moving to
c# so we've not been in there too much yet, but this seems to be kind of
pointless. if you have to initialize when you declare, why not just type
it for readability sake?

we watched the video on msdn, but still don't quite get it...

can someone give me a real world example of where this is useful?
 
Scott said:
Seems to me that we're going backwards on this.... towards
JavaScript/VBScript == Bad?

Scott,

Not quite. It is a confusing concept that may seem like a
JavaScript/VBScript typing system on the surface. The important thing
to remember, however, is that variable declarations are still
strongly-typed. They just happen to be inferred at compile time. Like
Nick said, this is required to implement anonymous types.

Brian
 
This angers a lot of C/C++/Java people because the syntax brings back
memories of VB's morphing not-really-typed variables, and nasty, sloppy
languages in which you can do stuff like this:

myVar = "Hello World";
myVar = 15;
myVar = Process.CurrentProcess;

etc.

Note that this is _not_ what implicit declarations in C# will give you.
They will produce strongly-typed variables, the only difference being
that you don't _need_ to specify the type of the variable... you can
let the compiler figure it out from context. So,

var myVar = "Hello World";

would make myVar a string, because it's obvious to the compiler that
you're initializing it to be a string. Thereafter, both of these would
be illegal:

myVar = 15;
myVar = Process.CurrentProcess;

would both fail with cast errors. Furthermore, you absolutely _can't_
do this:

var myVar;

because the compiler has no way of inferring type.

Personally, I like it. It eliminates a lot of needless typing. Yes, it
can (and will) be abused, although I don't necessarily agree that:

var myVar = "Hello World";

is an abuse. This, however, probably is (because a reader can't know
what type the variable is without doing additional research):

var myVar = SomeMethodOfMineThatReturnsStuff(a, b, c);
 
Yes, I understand. I just think it makes the language more sloppy, in
general. I just think explicit declarations should always be required.
 
Scott M. said:
Yes, I understand. I just think it makes the language more sloppy, in
general. I just think explicit declarations should always be required.

That's quite tricky in the case where you're using anonymous types as
provided by LINQ: an explicit declaration is *impossible* in that case.
I personally think that having anonymous types is worth the potential
problems of "var", although I would imagine that there'll be a lot of
code checkers which make sure you don't use it where you don't need
to...
 
Scott M. said:
Yes, I understand. I just think it makes the language more sloppy, in
general. I just think explicit declarations should always be required.

If you are interested in the topic, I strongly recommend you spend some time
looking at languages like Haskell or ML (OCaml, F#): they are strongly-typed
but they don't need type declarations because the compiler can infer them
all. This allows you to concentrate on the problem you are trying to solve
instead of the requirements of the language you are trying to solve it in.
Actually, given that I spend my professional life in an environment where
the main development language is a language you could define a dynamic
language, I am quite happy with this move towards a smarter compiler.
 
so, myself and the other developers i work with were looking at the v3.0
specifications. extensions look great, buy what is the point of implicit
variables with the 'var' type?

before you bash me too much, keep in mind, we're a delphi shop, moving to c#
so we've not been in there too much yet, but this seems to be kind of
pointless. if you have to initialize when you declare, why not just type it
for readability sake?

we watched the video on msdn, but still don't quite get it...

can someone give me a real world example of where this is useful?
It will be to a maintenance programmer's disadvantage.
Just my $0.02.

Good luck with your project,

Otis Mukinfus
http://www.arltex.com
http://www.tomchilders.com
 
Scott said:
Yes, I understand. I just think it makes the language more sloppy, in
general. I just think explicit declarations should always be required.

I think you're missing the bigger picture. Check out this video to see
some of the implications of this feature:

http://channel9.msdn.com/showpost.aspx?postid=114680

Consider this code (taken from the video):

Customer[] customers = SampleData.GetCustomers();

var q =
from c in customers
where c.city == "London"
select new { c.CompanyName, c.Phone };

What type is q? It is a list of an anonymous type that includes
CompanyName and Phone.

And using the same type inference you can use this code (also from the
video):

foreach (var x in q)
{
Console.WriteLine(x.CompanyName);
}

Watch the video, all the concepts depend on this type inference. Using
the most simple case: var s = "hello" is stupid, yes, but it is the
basis for all that follows.
 
Jon said:
That's quite tricky in the case where you're using anonymous types as
provided by LINQ: an explicit declaration is *impossible* in that case.
I personally think that having anonymous types is worth the potential
problems of "var", although I would imagine that there'll be a lot of
code checkers which make sure you don't use it where you don't need
to...

I wonder if a compiler warning could be added for the trivial misuse of
the var declaration. I'm not sure how feasible it would be...I'm just
thinking out loud right now.

Brian
 
Brian Gideon said:
I wonder if a compiler warning could be added for the trivial misuse of
the var declaration. I'm not sure how feasible it would be...I'm just
thinking out loud right now.

I'd been wondering the same thing, to be honest...
 
Brian said:
I wonder if a compiler warning could be added for the trivial misuse
of the var declaration. I'm not sure how feasible it would be...I'm
just thinking out loud right now.

Though when will that warning be raised? Ok, the obvious example:
var f = "Foo";

but what if a Linq query results in types which ARE there? Like you're
selecting a Customer instance from a list, and thus the type is
Customer, you KNOW that, you don't have to use an anonymous type. In
that case, the warning ALSO has to be raised IMHO (IF it's added).

Although I see a point in having a warning for var f = "Foo";, I also
think that if developers are sloppy, they simply won't even read
warnings or don't care about them. I mean, you can also whipe your
harddrive with one call to execute format c: /q, though no warning is
issued then. Similar when people use delegates and invoke all over the
place while it's completely unnecessary and thus makes the code
unreadable (at least in my opinion, complex code isn't synonym for good
code, on the contrary).

I.o.w.: Nice idea, but IMHO not possible.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
Nathan Laff said:
so, myself and the other developers i work with were looking at the v3.0
specifications. extensions look great, buy what is the point of implicit
variables with the 'var' type?


It was something that was required in order to implement LINQ. As a matter
of fact almost all of the 3.0 additions ( like extender methods) are
included to make LINQ works.

If this is good or bad, honestly I do not know. It gives you great
flexibility and a BIG expressing power , but this has a double edge, I'm
afraid of seeing code that will be impossible to understand and
debugging/troubleshooting some other people code if they decide to be
"overcreative" with these features.

It certainly will add complexity to the language and personally I'm afraid
that C# become the new C++ , superpowerful but with so many features that
only a few selected can masterize it. and this could alienate the market.
 
Frans Bouma said:
Though when will that warning be raised? Ok, the obvious example:
var f = "Foo";

but what if a Linq query results in types which ARE there? Like you're
selecting a Customer instance from a list, and thus the type is
Customer, you KNOW that, you don't have to use an anonymous type. In
that case, the warning ALSO has to be raised IMHO (IF it's added).

Although I see a point in having a warning for var f = "Foo";, I also
think that if developers are sloppy, they simply won't even read
warnings or don't care about them. I mean, you can also whipe your
harddrive with one call to execute format c: /q, though no warning is
issued then. Similar when people use delegates and invoke all over the
place while it's completely unnecessary and thus makes the code
unreadable (at least in my opinion, complex code isn't synonym for good
code, on the contrary).

I.o.w.: Nice idea, but IMHO not possible.

I don't think you've shown that it's not possible. If developers choose
to ignore warnings, so be it - that will always be the case. Personally
I always make sure code is warning free, and I believe other
conscientious developers do likewise.
 
Thanks Chris. I'll check it out.


Chris Dunaway said:
Scott said:
Yes, I understand. I just think it makes the language more sloppy, in
general. I just think explicit declarations should always be required.

I think you're missing the bigger picture. Check out this video to see
some of the implications of this feature:

http://channel9.msdn.com/showpost.aspx?postid=114680

Consider this code (taken from the video):

Customer[] customers = SampleData.GetCustomers();

var q =
from c in customers
where c.city == "London"
select new { c.CompanyName, c.Phone };

What type is q? It is a list of an anonymous type that includes
CompanyName and Phone.

And using the same type inference you can use this code (also from the
video):

foreach (var x in q)
{
Console.WriteLine(x.CompanyName);
}

Watch the video, all the concepts depend on this type inference. Using
the most simple case: var s = "hello" is stupid, yes, but it is the
basis for all that follows.
 
Jon said:
I don't think you've shown that it's not possible. If developers
choose to ignore warnings, so be it - that will always be the case.
Personally I always make sure code is warning free, and I believe
other conscientious developers do likewise.

Ok, but my point was that it's hard to make a warning which is
actually useful for the people who do read warnings like you and I. I
don't want a warning which says my valid code is actually wrong, e.g.
in the case when there IS a type available which could contain the
values in the resultset.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
Ignacio said:
It was something that was required in order to implement LINQ. As a
matter of fact almost all of the 3.0 additions ( like extender
methods) are included to make LINQ works.

If this is good or bad, honestly I do not know. It gives you great
flexibility and a BIG expressing power , but this has a double edge,
I'm afraid of seeing code that will be impossible to understand and
debugging/troubleshooting some other people code if they decide to be
"overcreative" with these features.

I think that's always the case when you reach a certain critical mass
of features: any random user will only use a subset of it and you can't
prevent duplicate ways of doing things anymore.

It's the duplicate ways of doing things which make things hard to
read. If there's a complicated way of doing a given thing A, but it's
the only way, no-one will bother. However as soon as there are two or
even more ways of doing the same thing A, or better: reaching the same
goal, you'll get groups of users who can't read / understand valid code
because they never use the way A is expressed in the given piece of
code.
It certainly will add complexity to the language and personally I'm
afraid that C# become the new C++ , superpowerful but with so many
features that only a few selected can masterize it. and this could
alienate the market.

That's already the case. Example: I personally never need to use
invoke directly in my code (only very very rarely) and almost never use
anonymous methods. However, there are people who use them regularly.
WHen I see their code, I have to look up the syntaxis sometimes to
understand what's going on, as I'm not familiar with it.

For example, can you write, without checking in the manual, a single
line piece of code which filters an List<T> on a given value for a
given property of T? I always have to lookup the anonymous method
syntaxis to write the predicate out, because I barely use it. The code
I then end up with looks odd to me, similar to these fancy typedefs in
the past which could emit cool code based on a single macro, like

typedef void (APIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);

:P

For a seasoned C developer this is simple, but for a person who rarely
uses typedef, it's hard to read. Similar to anonymous filter methods.
Like sorting a list:
toReturn.Sort( delegate( TemplateBindings a, TemplateBindings b ) {
return -(a.PrecedenceLevel.CompareTo( b.PrecedenceLevel )); } );

fancy code, one line, but I personally hate this kind of code, because
it already is complicated to read. And this is C# 2.0. But as I said: I
find it hard(er) to read because I rarely use this syntaxis, but a
person who uses it a lot (because s/he likes it, dunno) it might be
simple and straight forward.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
Back
Top