One of the reasons I don't view anonymous types as being too bad is that they're nicely confined to methods. You can't declare the type that you're returning from a method if it's anonymous (or if one of its type arguments is generic, e.g. a List<T>
where T
is an anonymous type and T
isn't a type parameter to the method itself). However, you can get around this if you're sneaky.
I've always known that it's perfectly easy to return an instance of an anonymous type by declaring that the method will return object
. However, it hadn't occurred to me before today that you can actually cast back to that type afterwards. Of course, you can't just use a normal cast expression - that requires the name of the type to be known at compile-time. But you can do a cast in a generic method... and you can use type inference to supply a type argument... and two anonymous type instance creation expressions will use the same type within the same assembly if the order, names and types of the properties are the same.
Behold the evil cheesecake factory!
static class GrottyHacks
{
internal static T Cast<T>(object target, T example)
{
return (T) target;
}
}
class CheesecakeFactory
{
static object CreateCheesecake()
{
return new { Fruit="Strawberry", Topping="Chocolate" };
}
static void Main()
{
object weaklyTyped = CreateCheesecake();
var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
new { Fruit="", Topping="" });
Console.WriteLine("Cheesecake: {0} ({1})",
stronglyTyped.Fruit, stronglyTyped.Topping);
}
}
The important thing to note here is that the stronglyTyped
variable really is of the same anonymous type as the one used in the CreateCheesecake
method. When we use the Fruit
and Topping
properties in the last statement, that's checked at compile-time.
Of course, it all goes pear-shaped if you make the slightest of errors when giving the Cast
method an example of what you want to cast to - if you got the order of the properties wrong, for example, the code would still compile, but the cast would throw an exception at execution time.
How useful is this? Ooh, probably not at all. Please do not use this "technique" in your code. If you do, at least don't mention my name anywhere near it. It's all fun though, isn't it?
...Full Article.
No comments:
Post a Comment
Post your comments here: