.Net: Var and Anonymous Types

September 30, 2014

Blog | Development | .Net: Var and Anonymous Types
.Net: Var and Anonymous Types

The ‘var’ keyword is the pinnacle of developer laziness. Introduced back in C# 3.0, it’s common for even the simplest of variable definitions to rely on the keyword rather than explicitly typing the value. Today, though, we’re going to look at the benefits of var with explicit type definitions.

For Type Changes


When you explicitly define a type as, for example, an int, you’re locking your logic into only being able to assign it as an int (ignoring implicit type conversions.) In some cases, this is a requirement for the task at hand, such as any logic performing bit-manipulation or comparison with the bounds of the type (e.g. Int32.MinValue and Int32.MaxValue). However, it’s very common for the underlying type of the numeric value to be totally irrelevant. If I have a value of 100, in theory the underlying type could be an Int8, Int16, Int32, or Int64 (byte, short, int, or long respectively) without altering the flow of my application in any way.


When using type inference, we can more easily change between similar types without necessitating dependent code changes.


As shown in the below example, the definition of the myValue variable need not be modified within the TestCode() method as a result of the GetMyValue() return type being altered.


Var - http://www.geekhive.com


For Clarity


When using LINQ, it’s fairly common to allow the compiler to infer the type of the variable by the output of the statement itself. For instance:


var myListOfInts = new List();
...
var myListOfSomethingElse = myListOfInts.Select(i => i.ToString());


 


The type above will result in an IEnumerable as a result of the Select statement returning an IEnumerable where the T type is the output of expression defined (“i.ToString()” in this case).


You may also have a situation where multiple filters are applied to a set and repeatedly re-defining the set to account for the different results would be wasteful. 


var myListOfInts = new List();
…
var filter1 = myListOfInts.Where(i => i <= 5);
…
var filter2 = filter1.Where(i => i >= 10);
…
var finalResult = filter2.Select(i => i.ToString())



Interlude



As a .Net developer, this may all seem obvious. However, did you know that Java, a language that is often compared to C# and whose syntax is so similar that a competent developer would barely have a bump changing between the two, only introduced the concept of type inference almost 4 years after? The syntax is pretty different, but accomplishes similar tasks.


List names = new ArrayList<>();



The “Diamond Operator”, as it’s called, allows the ArrayList constructor to be aware that an ArrayList of Strings must be created.

For Requirement

There are also some scenarios where the type is actually not something that can be expressed in the code itself.

var myListOfInts = new List();
…
var myListOfSomethings = myListOfInts.Select(i => new 
{
    IntValue = i, 
    StringValue = i.ToString()
});

In this case, our resulting object is an IEnumerable where T is some type that provides two read-only properties named IntValue and StringValue. T in this case is considered an Anonymous Type, known by the compiler to validate the remainder of the code as well as by the runtime, but not explicitly defined by the developer.

One hurdle with these anonymous types are that they cannot be directly used as return values. Of course, you can return the “Object” type but would be stuck on the receiving end trying to extract the values using reflection or witchcraft.

 

For Equality Checking

An interesting aspect of anonymous types is how they are checked for equality. An anonymous type is essentially an immutable data type containing values, and the .Equals() method is implemented to simply compare these values.

var myList1 = new List();
myList1.Add(1);
myList1.Add(2);

var myList2 = new List();
myList2.Add(1);

var myListOfSomethings = myList1.Select(i => new 
{
    IntValue = i, 
    StringValue = i.ToString()
}).ToArray();

var myOtherListOfSomethings = myList2.Select(i => new 
{
    IntValue = i, 
    StringValue = i.ToString()
}).ToArray();

var isEqual1 = myListOfSomethings.First().Equals(myListOfSomethings.First());
var isEqual2 = myListOfSomethings.First() == myListOfSomethings.First();
var isEqual3 = myListOfSomethings.First().Equals(myOtherListOfSomethings.First());
var isEqual4 = myListOfSomethings.First() == myOtherListOfSomethings.First();

The result for the above four boolean values are:

Var Table - http://www.geekhive.com

Food For Thought: The two .ToArray() invocations to execute the .Select() statement and materialize the arrays are the reason why IsEqual2 is true. Why? Because if the array was not materialize, the two invocations of myListOfSomethings.First() would execute the .Select() statement twice. The reason for this can be found in “The Accidental Repeater” section of my LINQ Your Way to Happiness.

For Greater Glory

These are just a few examples where the ‘var’ keyword comes in handy or is simply required to be able to develop the complex code that is required in some cases. Do you feel the keyword is overused in situations where the extra verbosity is more appropriate? Let us know @GeekHive.

 

Phil Azzi, Developer, GeekHive

Phil Azzi

Technical Lead
Tags
  • .NET
  • Tutorial

Recent Work

Check out what else we've been working on