A little var love
As we all know one of the things that LINQ gives us is anonymous types that can be
used by using the selection query operator, such as
1: var x = new { DateNow = DateTime.Now };
Which will give us an anonymous type with a single DateTime property called
"DateNow", which is all cool. This is largely thanks to the "var" keyword.
If you spend time working with the var keyword you will soon realise that
you can no longer work with the object that is declared as a "var" as a
strongly typed object outside the scope of the current method.
We can get around this by using the object type as a parameter where a
anonymous parameter could be passed. This is demonstrated in the following
screen shot. As we can see we are able to pass an anonymous type, but from
there we have an object type, so the only way to get at the values is by
using Reflection.
Here is an example that shows we can obtain the value of anonymous
types, well enough.
Anonymous can't be used as method results, unless the method return
type is object. This is why anonymous types should only be used
locally within methods. One place where this rule is broken is
within generic methods.
Consider the following example code.
1: /// <summary>
2: /// Simple generic method
3: /// </summary>
4: public static TResult
5: HaveSomeGenericFun<TResult>(Func<TResult> input)
6: {
7: return input();
8: }
9:
10: static void Main(string[] args)
11: {
12: //I am calling a generic method here passing it an
13: //anonomous type....curious
14: var obj = HaveSomeGenericFun(
15: () => new
16: {
17: Time = DateTime.Now,
18: ProcessName =
19: Process.GetCurrentProcess().ProcessName
20: });
21:
22: Console.WriteLine(String.Format(
23: "Process {0} was running at {1}",
24: obj.Time, obj.ProcessName));
25:
26: Console.ReadLine();
27: }
The return type of the HaveSomeGenericFun is generic. If we call it
without specifying a type for TResult, it is automatically inferred from
the signature of the "input" parameter. Because the "input" Func<TResult>
provided as an argument returns an instance of an anonymous type,
the HaveSomeGenericFun() generic method returns that type.
As can be seen that the HaveSomeGenericFun() method doesn't use an object
return value anywhere, so the return value will be strongly typed.
Whilst this is all well and good and pretty useless by and large, LINQ uses
this mechanism internally, and I just thought it was pretty interesting so
thought it may be worth a mention.
So there you have it, consider it mentioned.


























Pete said
am December 18 2008 @ 11:02 pm
Nice.
One thing to add when working with the “var” keyword is that a new annonymous type is created (you didn’t define a class/struct on your code), it’s immutable.
Pete said
am December 19 2008 @ 2:15 am
“as a strongly typed object outside”
I’d say “as a strongly typed immutable object outside”
Just a minor addition. Please don’t erase the comment. No harm intended.
Marlon Grech said
am December 20 2008 @ 6:29 am
cool trick…. This will be cooler when there is the dynamic keyword in C# 4.0
sacha said
am December 20 2008 @ 11:00 am
You bet, Grech. I am going to start looking at Dynamics real soon. Looks cool.