Welcome to MSDN Blogs Sign in | Join | Help
T CastByExample<T>(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?

Posted: Thursday, November 22, 2007 5:57 AM by AlexJ
Filed under: , ,

Comments

Adrian H. said:

匿名对象一般只在同一个Scope中定义和使用,这样才能让VS有Intellisence: 如果是通过函数传递过来的匿名类型对象,就只能用object来传了..当然也就没了Intellis...

# November 22, 2007 3:27 AM

littleguru said:

Hi Alex,

you should rename:

o.CastAsType(new { FullName = "" });

to

o.CastByExample(new { FullName = "" });

Greetings,

Christian

# November 22, 2007 6:18 AM

Leaning Into Windows said:

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

# November 22, 2007 1:00 PM

AlexJ said:

Thanks for the catch little guru...

# November 22, 2007 2:02 PM

rogerj said:

# November 24, 2007 12:42 PM

bittercoder said:

Thanks for the tip =) I'd always wondered if I could do something like that...

# November 25, 2007 4:35 PM

MatthieuMEZIL said:

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

# November 26, 2007 9:45 AM

Wriju's BLOG said:

One of the biggest limitation in “var” is that it cannot be shared across the methods. So if you are

# December 18, 2007 7:20 PM

Just code - Tamir Khason said:

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

# December 19, 2007 4:19 AM

Incoherent Rambling said:

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

# January 19, 2008 12:01 PM

aelij said:

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.

# March 20, 2008 9:59 AM
Anonymous comments are disabled
Page view tracker