Anonymous Types C#

3.6k views Asked by At

I understand that anonymous types have no pre-defined type of its own. Type is assigned to it by the compiler at the compile type and details of type assigned at compile time can't be known at code level; these details are known to CLR itself. I've heard that these anonymous types at CLR are treated as if it's a reference type only. So my question is that whether at compile time a new Type like a class or a struct is created corresponding to read-only properties defined in the anonymous type?

5

There are 5 answers

8
Eric Lippert On

I understand that anonymous types have no pre-defined type of its own.

Correct. There is no base type other than object common to anonymous types.

Type is assigned to it by the compiler at the compile type and details of type assigned at compile time can't be known at code level

That's correct.

these details are known to CLR itself.

I don't know what "details" you're talking about or what "known to CLR" means.

I've heard that these anonymous types at CLR are treated as if it's a reference type only.

You heard correctly.

So my question is that whether at compile time a new Type like a class or a struct is created corresponding to read-only properties defined in the anonymous type?

Yes. A new class is created.

Note that within an assembly if there are two anonymous types with the same property names, same property types, in the same order, then only one type is created. This is guaranteed by the language specification.

Exercise:

// Code in Assembly B:
public class B { protected class P {} }

// Code in Assembly D (references assembly B)
class D1 : B { 
  public static object M() { return new { X = new B.P() }; }
}
class D2 : B { 
  public static object M() { return new { X = new B.P() }; }
}

You are required to generate in assembly D a single class declaration that has a property X of type B.P such that D1.M().GetType() is equal to D2.M().GetType(). Describe how to do so.

0
Johnny On

These anonymous classes are derived directly from the object. Typically they are used in select LINQ queries to encapsulate read only properties into single object.

LINQ example(FirstName and LastName as FullName):

public class Person {
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

IEnumerable<int> personIds = persons
    .Select(p => new { Id = p.Id, FullName = p.FirstName + " " + p.LastName})
    .Where(a => a.FullName == "John Smith")
    .Select(a => a.Id);
1
Sergey Kalinichenko On

Other than having no programmer-accessible name, anonymous types are pretty straightforward: compiler generates them based on the assignments that you make, and takes care of properly merging identical anonymous types from the same method into a single run-time type.

According to C# language specification, section 7.6.10.6, anonymous types are always classes, not structs. An anonymous object initializer of the form

new { p1 = e1 , p2 = e2 , ... pn = en }

declares an anonymous type of the form

class __Anonymous1 {
    private readonly T1 f1 ;
    private readonly T2 f2 ;
    ...
    private readonly Tn fn ;
    public __Anonymous1(T1 a1, T2 a2,…, Tn an) {
        f1 = a1 ;
        f2 = a2 ;
        ...
        fn = an ;
    }
    public T1 p1 { get { return f1 ; } }
    public T2 p2 { get { return f2 ; } }
    ...
    public Tn pn { get { return fn ; } }
    public override bool Equals(object __o) { … }
    public override int GetHashCode() { … }
}
0
Jörg W Mittag On

Anonymous types are a C♯ feature that has no equivalent on the CLI. They are simply compiled to normal types, with a very long and very complicated name chosen by the compiler. Note that the spec guarantees that two anonymous types with the same structure (within the same assembly) are actually the same type, so the compiler needs to take that into account, too, and only generate one type (and generate the same name for both usage sites).

0
Xiaoy312 On

Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object. The compiler provides a name for each anonymous type, although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type.

Source: https://msdn.microsoft.com/en-us/library/bb397696.aspx