Question

Is there anything to use, to determine if a type is actually a anonymous type? For example an interface, etc?

The goal is to create something like the following...

//defined like...
public static T Get<T>(this IAnonymous obj, string prop) {
    return (T)obj.GetType().GetProperty(prop).GetValue(obj, null);
}
//...

//And then used like...
var something = new { name = "John", age = 25 };
int age = something.Get<int>("age");

Or is that just the beauty of an anonymous type? Nothing to identify it self because it takes a new shape?

Note - I realize that you can write an extension method for the object class, but that seems like a little overkill, in my opinion.

Was it helpful?

Solution

EDIT: The list below applies to C# anonymous types. VB.NET has different rules - in particular, it can generate mutable anonymous types (and does by default). Jared has pointed out in the comment that the naming style is different, too. Basically this is all pretty fragile...

You can't identify it in a generic constraint, but:

  • It will be a class (rather than interface, enum, struct etc)
  • It will have the CompilerGeneratedAttribute applied to it
  • It will override Equals, GetHashCode and ToString
  • It will be in the global namespace
  • It will not be nested in another type
  • It will be internal
  • It will be sealed
  • It will derive directly from object
  • It will be generic with as many type parameters as properties. (You can have a non-generic anonymous type, with no properties. It's a bit pointless though.)
  • Each property will have a type parameter with a name including the property name, and will be of that type parameter, e.g. the Name property becomes a property of type <>_Name
  • Each property will be public and read-only
  • For each property there will be a corresponding readonly private field
  • There will be no other properties or fields
  • There will be a constructor taking one parameter corresponding to each type parameter, in the same order as the type parameters
  • Each method and property will have the DebuggerHiddenAttribute applied to it.
  • The name of the type will start with "<>" and contain "AnonymousType"

Very little of this is guaranteed by the specification, however - so it could all change in the next version of the compiler, or if you use Mono etc.

OTHER TIPS

As I recall, there is a [CompilerGenerated] marker... 2 secs

Plus the name will be freaky, and it will be a generic type ;-p

Actually, for a "get" etc I would probably just use a static (non-extension) method.

If you just want a way to get the value from an instance of an anon-type (at a later point in time), a lambda is probably the best option - note you need a few tricks to pull this off:

    static void Main()
    {
        var foo = new { name = "John", age = 25 };
        var func = Get(foo, x => x.age);
        var bar = new { name = "Marc", age = 30 };
        int age = func(bar);
    }
    // template here is just for type inference...
    static Func<TSource, TValue> Get<TSource, TValue>(
        TSource template, Func<TSource, TValue> lambda)
    {
        return lambda;
    }

(edit re the comment) There definitely is this attribute:

        var foo = new { A = "B" };
        Type type = foo.GetType();

        CompilerGeneratedAttribute attrib = (CompilerGeneratedAttribute) Attribute.GetCustomAttribute(
            type, typeof(CompilerGeneratedAttribute)); // non-null, therefore is compiler-generated

For the purposes of extension methods there is no way to distinguish an anonymous type. Extension methods work by specifying a method for a compile time nameable type. Anonymous types are un-namable and therefore not visible at compile time. This makes them incompatible with extension methods.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top