Anonymous Types - Are there any distingushing characteristics?
Solution 1:
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.
Solution 2:
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