What to Use: Var or Object Name Type

What to use: var or object name type?

Beyond the obvious use of var with LINQ, I also use it to abbreviate hairy variable declarations for readability, e.g.:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

In general, I get a kind of comfort (for want of a better word) from static typing that makes me reluctant to give it up. I like the feeling that I know what I'm doing when I'm declaring a variable. Declaring a variable isn't just telling the compiler something, it's telling the person reading your code something.

Let me give you an example. Suppose I have a method that returns a List<string>. This code is certainly correct, and I think it's how 90% of C# developers would probably write it:

List<string> list = MyMethod();

Obviously, right? In fact, here's a place you could just as easily use var.

True enough. But this version of the code isn't just declaring a variable, it's telling me what the person who wrote it is intending to do:

IEnumerable<string> list = MyMethod();

The developer who wrote that code is telling me "I'm not going to be changing this list, nor am I going to use an index to access its members. All I'm going to do is iterate across it." That's a lot of information to get across in a single line of code. It's something you give up if you use var.

Of course, you're not giving it up if you weren't using it in the first place. If you're the kind of developer who would write that line of code, you already know that you wouldn't use var there.

Edit:

I just reread Jon Skeet's post, and this quote from Eric Lippert jumped out at me:

Implicitly typed locals are just one small way in which you can deemphasize the how and thereby emphasize the what.

I think that actually in a lot of cases using implicit typing is leaving the what implicit. It's just OK to not dwell on the what. For instance, I'll casually write a LINQ query like:

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
where r.Field<bool>("Flag")
orderby r.Field<int>("SortKey")
select r;

When I read that code, one of the things I think when I'm reading it is "rows is an IEnumerable<DataRow>." Because I know that what LINQ queries return is IEnumerable<T>, and I can see the type of the object being selected right there.

That's a case where the what hasn't been made explicit. It's been left for me to infer.

Now, in about 90% of the cases where I use LINQ, this doesn't matter one tiny little bit. Because 90% of the time, the next line of code is:

foreach (DataRow r in rows)

But it's not hard to envision code in which it would be very useful to declare rows as IEnumerable<DataRow> - code where a lot of different kinds of objects were being queried, it wasn't feasible to put the query declaration next to the iteration, and it would be useful to be able inspect rows with IntelliSense. And that's a what thing, not a how thing.

Why should I use var instead of a type?

It's really just a coding style. The compiler generates the exact same for both variants.

See also here for the performance question:

  • Will using 'var' affect performance?

When should I use var instead of object?

You misunderstand: var isn’t a type. var instructs the compiler to use the correct type for a variable, based on its initialisation.

Example:

var s = "hello";         // s is of type string
var i = 42; // i is of type int
var x = new [] { 43.3 }; // x is of type double[]
var y = new Foo(); // y is of type Foo

Your variables are still strongly typed when using var.

As a consequence, var isn’t “evil”. On the contrary, it’s very handy and as I’ve said elsewhere, I use it extensively. Eric Lippert, one of the main people behind C#, has also written in great detail about whether var is bad practice. In a nutshell, “no”.

C# var keyword usage

I think it's fine to use var where it makes the code easier to read, which for me would mean that the type that var is replacing must be completely obvious.

For example, this would be a good use of var (contrived example):

var thing = new Dictionary<int, KeyValuePair<string, int>>();

However this would be a bad use of var:

var thing = GetThingFromDatabase();

Why does ReSharper want to use 'var' for everything?

One reason is improved readability. Which is better?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

or

var dictionary = new Dictionary<int, MyLongNamedObject>();

Why use var instead of the class name?

Imagine this.

Dictionary<Dictionary<String, String>, String> items = new Dictionary<Dictionary<String, String>, String>();

var is useful for things like that.

var items = new Dictionary<Dictionary<String, String>, String>();

Much simpler. The point of var is the same as auto in C++ 11, the compiler knows the type so why must we repeat ourselves so much. I personally use var rarely, but only for lengthly declarations. It's just syntactic sugar.

Advantage of var keyword in C# 3.0

It's mostly present for LINQ, when you may use an anonymous type as the projection:

var query = from person in employees
where person.Salary > 10000m
select new { FullName=person.Name, person.Department };

Here the type of query can't be declared explicitly, because the anonymous type has no name. (In real world cases the anonymous type often includes values from multiple objects, so there's no one named class which contains all the properties.)

It's also practically useful when you're initializing a variable using a potentially long type name (usually due to generics) and just calling a constructor - it increases the information density (reduces redundancy). There's the same amount of information in these two lines:

List<Func<string, int>> functions = new List<Func<string, int>>();
var functions = new List<Function<string, int>>();

but the second one expresses it in a more compact way.

Of course this can be abused, e.g.

var nonObviousType = 999999999;

but when it's obvious what the type's variable is, I believe it can significantly increase readability.

What is the (type) in (type)objectname.var

It is casting(converting) the numericUpDown1.Value to an int value. This can also be done using

Convert.toInt32(numericUpDown1.Value)

I'm assuming that dinnerParty.NumberOfPeople is an integer value and therefore if you didn't cast it would throw an error if the value supplied was not an integer. For example if the Value supplied was a double or a string it would throw an error, with casting it would convert the double say 20.5 to 20 and it would be accepted. For the string it would depend on if the string contained a number in it. If the string was "12" then using the convert method mentioned above would convert it to the integer 12.

Use of var keyword in C#

I still think var can make code more readable in some cases. If I have a Customer class with an Orders property, and I want to assign that to a variable, I will just do this:

var orders = cust.Orders;

I don't care if Customer.Orders is IEnumerable<Order>, ObservableCollection<Order> or BindingList<Order> - all I want is to keep that list in memory to iterate over it or get its count or something later on.

Contrast the above declaration with:

ObservableCollection<Order> orders = cust.Orders;

To me, the type name is just noise. And if I go back and decide to change the type of the Customer.Orders down the track (say from ObservableCollection<Order> to IList<Order>) then I need to change that declaration too - something I wouldn't have to do if I'd used var in the first place.



Related Topics



Leave a reply



Submit