Started learning anonymous types in C #.
The author gives an example of the syntax of an anonymous type var instance = new { Name = "Alex", Age = 27 }; and proposes sequentially - step by step to add additional syntax elements to this line so that the given lines become more recognizable “readable” for us (I remind you: the author does this because the example and the whole course is educational). turning the above string into

 var instance = new MyClass() { Name = "Alex", Age = 27 }; 

saying that we added the default constructor name and parentheses for accepting constructor arguments, and immediately demonstrate that by adding this — the studio offers us to generate properties for Age and Name in the MyClass class (he created the class himself — again, for example, but said that in anonymous types, when generating properties, a class is also automatically created). In class generated autorealizable properties

enter image description here

But the author said that they should be read-only, i.e. in (well, in this case you need to remove set permanently - after all, the studio generated properties as for ordinary class fields when we added the default constructor name after the new keyword). And that brings me to question number 3 (questions number 1 and number 2 are presented below). If auto-generated, auto-implemented properties in a class that is also automatically created (let's call it MyClass ) are read-only, then how in the initializer block on the line var instance = new { Name = "Alex", Age = 27 }; we generally can assign values ​​to these fields? Here is a screenshot of the first example in which I am interested in a comment, in which I have all these questions. enter image description here

Question number 1: i.e. does the compiler create a new name for an anonymous type each time, which in turn is a reference type?

Question number 2: i.e. an application cannot refer to a link (since the type is reference) to a new name created by the compiler.

Question number 3 is presented at the beginning.

  • The second question is not at all clear - Grundy
  • I mean, I don’t understand why the generated names for anonymous types are inaccessible to the application? - BadCatss
  • I apologize for question number 2 - there was a cant - corrected. now it sounds so Question №2 ie the application can not refer to (reference type) to the new name created by the compiler? - BadCatss

1 answer 1

  1. Yes, so conceived. The compiler creates a name like <>f__AnonymousType0 , which cannot be used from C #. It cannot be accessed simply because such names cannot be used in C #. But you can easily see this name with the help of reflection:

     class Program { public static void Main() { var o = new { x = 5, y = 8 }; foreach (var t in Assembly.GetExecutingAssembly().GetTypes()) Console.WriteLine(t.Name); } } 

    gives out

    <> f__AnonymousType0`2
    Program
    Settings

    ( `2 means that the class is in fact a generic class for the reasons given here )

  2. The program may well refer to the values ​​of this type. It simply cannot get the type name to, for example, declare the type of the return value. A reading request works:

     var o = new { x = 5, y = 8 }; // var необходим, т. к. мы не можем назвать имя Console.WriteLine(ox); // обращение по ссылке 
  3. No, you cannot assign anonymous type properties. They are created without a setter at all. In fact, here is the code:

     var o = new { x = 5, y = 8 }; 

    generates (approximately) the following class:

     [DebuggerDisplay("{ x = {x}, y = {y} }", Type = "<Anonymous Type>")] public sealed class Anonymous<TX, TY> { private readonly TX field_x; private readonly TY field_y; public TX x { get { return field_x; } } public TY y { get { return field_y; } } [DebuggerHidden] public Anonymous(PX x, PY y) { field_x = x; field_y = y; } public override bool Equals(object value) { /* тут имплементация */ } public override int GetHashCode() { /* тут имплементация */ } public override string ToString() { /* тут имплементация */ } } 

    and your call to the compiler turns into the following:

     Anomymous<int, int> o = new Anonymous<int, int>(5, 8); 

    You see, in fact, there is no assignment of properties, but simply a call to the constructor. Therefore, further recording in the same properties is impossible.

  • It cannot be accessed just like that, because such names cannot be used in C # - even simpler, because this name is unknown until compilation. - Grundy
  • @Grundy: Well, even if we compile this module, we will find out the name after this, and now we will try to use it from another module, it will not roll. - VladD
  • Didn't quite understand what you mean :) - Grundy
  • one
    Isn’t he able to use it through reflection? :-) - Grundy
  • 3
    @VadimOvchinnikov: Hm, maybe it’s better not to tell newbies for the time being? And then they will start to write a terrible architecture, hoping for a reflection or there unsafe-code to modify what can not be modified. - VladD