<

The var keyword

Published on
17,167 Points
6,967 Views
7 Endorsements
Last Modified:
Awarded
Community Pick
Introduction
                                               
Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.
 
Also called: Implicitly typed local variables
 
The var keyword – in VB
 
I have heard many an argument about this new addition to the C# language. One of the main debates being: It’s so VB like, It reminds me of Dim.  So this is all I am going to say about its use in VB (and only because I think if VB programmers use it may make their code just a little better).
 
Its use in VB is slightly different to that in C#.  This is because VB has always had an unknown type keyword (dim), so you have to explicitly “turn on” the functionality by using the “Option Infer On” at the top of your module.  So to finish off for VB: To use this functionality turn it on and the declare your Variable like so:
 
   Dim MyStringVariable = "hello world"
 
When hovering the mouse over MyStringVariable you will notice the tooltip text says Dim MyStringVariable As String.  So you will not be able to do your usual VB thing and change its type later on to an int!
 
The var keyword
 
First of all to ease all your minds the var keyword is not evil VB code creeping into your C# IDE!  It is strongly typed (which means that you cannot put a string into it and then later on change its type to an int).
 
It must not be confused with the object data type – it is also not an object.  So what is it?  It is whatever you want it to be when declaring the variable.  So if you type:
 
string MyString = "Hello world"; 
Console.WriteLine(MyString);

Open in new window

 
It is no different from typing
 
var MyString = "Hello world"; 
Console.WriteLine(MyString);

Open in new window

 
In fact, when you compile it the IL Code will look like this for both scenarios.
.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] string MyString)
    L_0000: nop 
    L_0001: ldstr "Hello world"
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: call void [mscorlib]System.Console::WriteLine(string)
    L_000d: nop 
    L_000e: ret 
}

Open in new window



 So what is the point - Is all this effort really to save me from typing out the extra three chars that there are in the word string?  Well yes, and no.  

First we will explore the Yes answer.  Since the addition of Generics in C# two  lines of code can become very long.  For instance:
 
Line1:  List<string> MyStringList = new List<string>();

Open in new window

Is shortened to

Line 2:  var MyStringList = new List<string>();

Open in new window


As you can imagine, some declarations can become quite long.

In line 1 you are saying:  I am declaring a List of strings and I want to assign it to a list of strings object.  Using the var keyword you are saying that I have a variable and it is a list of strings – you don’t have to say it twice.  To strengthen this point: You cannot declare a var and then initalise it later.  When using the var keyword you have to initalise it on the same line (Only exception is that you cannot initalise it using a collection initaliser).  And you cannot initalise it to a Lamda expression.
 
The following lines of code are errors and will not compile:
var x;

Open in new window

var x = null;

Open in new window

var x = {"1", "2"};

Open in new window

var x = () => { j = 10; return j > 9; };

Open in new window


Now we shall explore the No part of the answer.  

All this effort in not only to save me from typing out the extra three chars in the word "string."  There are actually types in C# that have no name.  These are called Anonymous types.  They are not any conventional type of object, but they do exist and you cannot initalise them without using the var keyword.
 
Example 1:
 
var Car = new { Manufacturer = "Audi", Model = "A4", Year = 2006, Colour = System.Drawing.Color.Blue };
Console.Write(Car.Colour + " " + Car.Manufacturer + " " + Car.Model + " " + Car.Year);

Open in new window



As you can see from the (pretty useless) example above that we now have an object which we don’t know what its name is, but we have assigned the variable Car to it, and Car has all of the valid properties to it. However it will print out to the console:
 
Color [Blue] Audi A4 2006
 
Example 2:
 
A more useful example would be when querying an Object / XML /  Anything using Linq.
 
var Articles = (from a in context.Articles
                orderby a.CreateDateTime descending 
                select  new { ArticalTitle = a.Title, Created= a.CreateDateTime }).Take(5);
        
foreach (var article in Articles )
{
     string s = article.ArticalTitle;
     DateTime d = article.Created;
}

Open in new window



So instead of bringing back the SQL whole object (in this case) a new anonymous object is created and returned. This I suppose was the main reason for the keyword.
 
Conclusion
 
Using var should be embraced by developers worldwide. There is no way to misuse this keyword.  It is always good!  The only conceivable reason not to use it would be if you don’t know the data type of the “RHS” of the =. This could possibly lead to reading issues ... but not really.  Ie:
    var x = 0;  
you know 0 is an int.  Therefore x is an int.  However
    var c = MyObject.variable;
(a newbie to the project may not know what datatype variable is of class MyObject).  Developers working with the project should know.  Moreover, correctly named variables should sort out this issue.  Example: Without knowing anything about a class we could guess that the property StartDate is a type of System.DateTime.  Else whip the developer if it's a string!!!

Originally Posted @ http://www.zadeveloper.com/
7
Comment
Author:zadeveloper
  • 4
  • 3
  • 3
  • +4
15 Comments
 
LVL 9

Expert Comment

by:rg20
Just curious in you example

 var Car = new { Manufacturer = "Audi", Model = "A4", Year = 2006, Colour = System.Drawing.Color.Blue };
Console.Write(Car.Colour + " " + Car.Manufacturer + " " + Car.Model + " " + Car.Year);

Considering Car is a method of transportation or a vehicle, could it not be referenced by it's class name

Car car
Transportation Car
Automobile Car

Or whatever the class defines it as?

Your second example your right I don't know what that could be.  
0
 
LVL 13

Author Comment

by:zadeveloper
Hi rg20.

In the example Car is created as an object of an unknow type, as there is no class/ interface defining "car".  In production this is not something I would recommend doing in this senario. The example was given to show that the variable Car can be used after it definition and the ide and compiler are aware of the properties created withing the parenthisis. (ie: Manufacturer, Model etc..)- althouggh I dont have a definition for that object type. (Hence I have to assign it by using var)

In development I have not yet come across a senario that I would use this sort of object instantiation, however I think I would use it instead of creating a class that I will only use once, or to create a object with a subset of properties.

senario where I may consider using it:

I might have a class called Automobile which has 50 properties, Now lets say Im writing a wcf service which passes data over the internet. now the user has asked for the color, make and model of the cars to be returned. I would create a object like this:

var car = new Automobile (some parameters);
// at this point car contains 50 properties (1 of which is a 10 MB image)

var result = new { Model = car.Model, Make= car.Make, Colour = car.Colour };

then I would return the object result to the user - using only the required amount of bandwidth :)

hope this helps :)

then I would do something like this:


0
 
LVL 13

Author Comment

by:zadeveloper
sorry - please ignore the last line
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 9

Expert Comment

by:rg20
that makes sense, but the only time I use var is during a LINQ query, but I think thats becuase I am not smart enough at this point to know what is coming back to me.  I don't have a lot of time to figure it out either.  ;)

Thanks
0
 
LVL 2

Expert Comment

by:joep_b
I guess the var-keyword has two big reasons to exist.

One is being able to use automatically generated types like your Car.

The second one is to make the existance of Linq possible:
I'd hate code to be littered with definitions like Dictionary<int,OrderedQuery<IQueriable<Group<Expression<Car>>>>> and them getting me in trouble when I decide I don't need the result to be ordered after all.
0
 
LVL 1

Expert Comment

by:DragonWolf
I'm in favour of using the var keyword where possible but I disagree with the last piece of your conclusion slightly,

var myVariable = this.GetSomeVariable()

In this case, I would avoid using the var keyword as it is unclear what the variable is. Your argument may be that the variable name and the method name should be meaningful, such as,

var startDate = this.CalculateNewStartDate();

Like this is better, and is probably a DateTime, but you still don't know,

var duration = this.CalculateDuration();

is worse since at a glance, it is not obvious if this is a TimeSpan, int, long, uint, ulong, Decimal, etc. In this case, I think you should explicitly declare the variable type.

TimeSpan duration = this.CalculateDuration();

Although you can use intellisense, I still like to be able to look at something's declaration and know instantly what it is. And if you aim for the "no method should be more than 10 lines of code" practise, then your declaration should always be on the same screen (no scrolling back to find the declaration).
0
 
LVL 13

Author Comment

by:zadeveloper
Hey DragonWolf

Thanks for the comment. I think that in such a case its a matter of personal taste (as it really does not matter to the compiler how you declare the variable).

I try to follow the "Don't have stupid method names" approach. However there are times like:

var duration = this.CalculateDuration();

where the type is not very clear. In this case its only difficult to read on paper and a mouse over will identify the strong type.

But pretty much its up to the developer/ developer team standards that would dictate this call.

Thanks for the input.
0
 
LVL 8

Expert Comment

by:TheMozz
Excellent write up, I look forward to seeing more from you!
0
 
LVL 36

Expert Comment

by:it_saige
You might also add that while the following is unacceptable:
// This is not acceptable
var x = null;

Open in new window

This is valid and acceptable -
var x = default(int); // This is 0
// Or
var y = default(string); // This is null
// Or
var z = default(SomeReferenceType); // This too is null

Open in new window


-saige-
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
@it_saige

That's because null doesn't have a type. If you simply cast, then you give the compiler enough information regarding the type in play:

var x = (string)null;  // valid

Open in new window

0
 
LVL 36

Expert Comment

by:it_saige
@kaufmed,

Yes, that works for reference types but does not give you a *strict* value type; e.g. -
var x = (int)null; // Valid, but results in an int wrapped in a nullable; e.g. - Nullable<int> or int?

Open in new window

Which could just be splitting hairs but also why I prefer using the default keyword.

-saige-
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
A value type can never be null, so the point is moot. A nullable value type would work, though.

The "problem" with default--and mind you I really have no issue with default in general--is you have to know what the default value for the thing you are assigning is when you write it. The list isn't exhaustive, so it's not that big of a deal.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
Also, your last example is not valid.
0
 
LVL 36

Expert Comment

by:it_saige
Agreed on all points.

But in reality, do you have to *know* what the result of using default on a type is?  Can you just not check for type to default(type) equality [or inequality] by using:
SomeType == default(SomeType)

Open in new window

As you have attested, the list is not exhaustive and, for the most part, is intuitive.

Can I blame my last example on poor coffee intake?  ;)

-saige-
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
Contrived example, but:

int x = 10;
int y = default(int);

double z = x / y;

Open in new window


I agree, it's mostly intuitive:  number types are all zero, and reference types are null.
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Join & Write a Comment

When you have multiple client accounts to manage, it often feels like there aren’t enough hours in the day. With too many applications to juggle, you can’t focus on your clients, much less your growing to-do list. But that doesn’t have to be the cas…
See the Basics of Office 365's Note Taking app, OneNote
Next Article:

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month