T CastByExample(object o, T example)
So earlier today I was lamenting that an anonymous type can't be shared between functions with Wes Dyer, when he said "Well actually they can..."
Cue me learning something cool.
The first step is to create a seemingly innocent method:
public static T CastByExample<T>(this object o, T example)
{
return (T) o;
}
Seems innocent enough right?
Well it is until you start using it with anonymous types. Imagine you had this function, that returns an anonymous type as object, because that is your only choice:
static object GetAnonymousType()
{
return new { FullName = "Cosmo Kramer" };
}
Normally if you called this function anywhere you wouldn't be able to get at the anonymous type without using reflection... This is where CastByExample<T> comes to the rescue.
If you know the shape of the anonymous type, you use that to do a CastByExample...
object o = GetAnonymousType();
//get the original anonymous type back again
var v = o.CastByExample(new { FullName = "" });
//Use the properties of the anonymous type initialized in another
//function directly !!
Console.WriteLine(v.FullName);
This works because when an anonymous type is used the compiler first checks that one with the same signature (i.e. all fields are the same name and type) hasn't already been used. If one has the same CLR type is used.
Hence if you pass in an example that is the same shape as the original anonymous type to the CastByExample<T>(..) method will get you back to the original anonymous type... and var magic does the rest.
Nifty huh?
Comments
Anonymous
November 21, 2007
匿名对象一般只在同一个Scope中定义和使用,这样才能让VS有Intellisence: 如果是通过函数传递过来的匿名类型对象,就只能用object来传了..当然也就没了Intellis...Anonymous
November 21, 2007
Hi Alex,you should rename:o.CastAsType(new { FullName = "" });too.CastByExample(new { FullName = "" });Greetings,ChristianAnonymous
November 22, 2007
Rick Strahl talks about new C# 3.0 features , but leaves a few questions… Why can’t you change the propertyAnonymous
November 22, 2007
Thanks for the catch little guru...Anonymous
November 24, 2007
Welcome to the Entity Framework fray.--rjhttp://oakleafblog.blogspot.com/2007/11/link-and-entity-framework-posts-for.htmlAnonymous
November 25, 2007
Thanks for the tip =) I'd always wondered if I could do something like that...Anonymous
November 26, 2007
It's a great idea to use an extension method. I did the same (without extension method) to get the elements of an anonymous typed List. What is funny in my sample is that I create the List using reflection, so without use an IEnumerable first.http://blog.developpez.com/index.php?blog=121&title=c_3_0_creer_une_liste_de_types_anonymes&more=1&c=1&tb=1&pb=1Anonymous
December 18, 2007
One of the biggest limitation in “var” is that it cannot be shared across the methods. So if you areAnonymous
December 18, 2007
Did you try to cast anonymous types (vars)? You are. However, you never was able to pass var from oneAnonymous
January 19, 2008
I was reading this particular entry from AlexJ's blog, in which he discussed how to use anonymousAnonymous
March 20, 2008
Great tip! I also added to these two:public static IEnumerable<T> CastByExample<T>(this IEnumerable o, T example){ return (IEnumerable<T>)o;}public static IQueryable<T> CastByExample<T>(this IQueryable o, T example){ return (IQueryable<T>)o;}Now I can create methods that return the non-generic IEnumerable and IQueryable interfaces.Anonymous
September 17, 2008
You've been kicked (a good thing) - Trackback from DotNetKicks.comAnonymous
January 01, 2009
[This blog was migrated. You will not be able to comment here. The new URL of this post is http://khasonAnonymous
November 10, 2009
Alex and Eli ArbelYour extension methods are big help when working on EF level and want to use functions which may returnanonymous type (or IEnumerable<anonymous type>)Thanks!Anonymous
March 21, 2012
Awesome!!.. I was having a bad day with anonymous types.. as result of an lambda expression via LinQ to SQL.Thank you for this useful tip.Cheers.CQ