Partager via


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,Christian

  • Anonymous
    November 22, 2007
    Rick Strahl talks about new C# 3.0 features , but leaves a few questions… Why can’t you change the property

  • Anonymous
    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.html

  • Anonymous
    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=1

  • Anonymous
    December 18, 2007
    One of the biggest limitation in “var” is that it cannot be shared across the methods. So if you are

  • Anonymous
    December 18, 2007
    Did you try to cast anonymous types (vars)? You are. However, you never was able to pass var from one

  • Anonymous
    January 19, 2008
    I was reading this particular entry from AlexJ&#39;s blog, in which he discussed how to use anonymous

  • Anonymous
    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.com

  • Anonymous
    January 01, 2009
    [This blog was migrated. You will not be able to comment here. The new URL of this post is http://khason

  • Anonymous
    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