简体   繁体   中英

Anonymous Types C#

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?

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 BP such that D1.M().GetType() is equal to D2.M().GetType() . Describe how to do so.

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

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 struct s. 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() { … }
}

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);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM