LINQ and Implicit variable |
Declaring implicit variable using ‘Var’ keyword should be restricted is one of the recommendations in the c# specification. The reason could be that many of the new features of c# 3.0 have direct relation with LINQ and these new feature suits LINQ rather than normal programming. Let’s explore the implicit variable and LINQ relation. |
|
A very good example and a simple one is given at http://msdn.microsoft.com/en-us/library/bb384061.aspx. It explains using a simple string. For you convenience I will put the example here (figure 7), now if you replace 2 instances of var with string[] and string respectively, since string look like a more likely type for ‘var’ here, you will be tempted to think replacing var with string makes things easier then, why ‘var’. However, doing so will result in following error. |
ERROR :Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'string[]'
|
class ImplicitlyTypedLocals2 { static void Main() { string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
// If a query produces a sequence of anonymous types, // then use var in the foreach statement to access the properties. var upperLowerWords = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() };
// Execute the query foreach (var ul in upperLowerWords) { Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower); } } }
/* Outputs: Uppercase: APPLE, Lowercase: apple Uppercase: BLUEBERRY, Lowercase: blueberry Uppercase: CHERRY, Lowercase: cherry */ /td> |
Figure 7 |
I know using string or build-in type is easy to relate, so let’s take a new example to understand the same scenario. Look at the code in figure8.Here instead of string we declare a class called SomeReturnClass and created a list< SomeReturnClass > with three values, to enable enumeration. Here use of ‘var’ cannot be replaced by SomeReturnClass for two reasons, SomeReturnClass does not have any constructor that take two int as parameters, the statement select new { x = w.updateValueI(), y = w.updateValueJ() }; therefore does not related to SomeReturnClass, therefore it’s more accurate to declare the output as ‘var’ and let compiler decide the type(Can call it anonymous type). Coming to the second use of ‘var’ at foreach (var v in objReturnClassX) , its very clear than objReturnClassX hold a type that better to be interpreted by compiler(anonymous type). Neither we have explicit convertion between ‘var’ and SomeReturnClass. |
namespace CSharpFeatures {
class ImplicitVariableLINQ { public static void GetImplicitVarLINQ() { List objReturnClassA = new List { new SomeReturnClass { i=0, j=2 }, new SomeReturnClass { i=2, j=2 }, new SomeReturnClass { i=2, j=0} }; var objReturnClassX = from w in objReturnClassA select new { x = w.updateValueI(), y = w.updateValueJ() };
foreach (var v in objReturnClassX) { Console.WriteLine("i:{0}, j:{1} ", v.x, v.y); } } static void Main(string[] args) { ImplicitVariableLINQ.GetImplicitVarLINQ(); Console.ReadLine(); } }
class SomeReturnClass { public int i, j; public SomeReturnClass() { }
public int updateValueI() { if (i <= 0) i = 100; else i = i + j; return i; } public int updateValueJ() { if (j <= 0) j = 200; else j = j + i; return j; } } }
|
Figure 8 |
OUTPUT |
|