Anonymous Types - Are there any distingushing characteristics?

前端 未结 3 1311
别那么骄傲
别那么骄傲 2020-11-27 04:57

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...

相关标签:
3条回答
  • 2020-11-27 05:34

    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.

    0 讨论(0)
  • 2020-11-27 05:43

    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.

    0 讨论(0)
  • 2020-11-27 05:52

    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
    
    0 讨论(0)
提交回复
热议问题