Всем привет, имеется вот такой пример:
class Program
{
static void Main()
{
// Анонимные типы в анонимных типах.
var instance = new { Name = "Alex", Age = 27, Id = new { Number = 123 } };
Console.WriteLine("Name = {0}, Age = {1}, Id = {2}", instance.Name, instance.Age, instance.Id.Number);
// Delay.
Console.ReadKey();
}
}
Как видно, в данном примере - один анонимный тип вкладывается в другой. Я понял, что это можно изобразить примерно так:
Также как я понял, когда я создаю анонимный тип, Visual Studio создает новый класс и новый класс создается когда компилятор встречает новый анонимный тип. Новизна определяется путем сравнения имен свойств, их порядка и типов. И получается, что когда я создаю новый анонимный тип, то Visual Studio порождает (примерно) следующий класс:
[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() { /* тут имплементация */ }
}
Но если у меня один анонимный тип вложен в другой, то эти порожденные классы будут Nested классами ли нет?
Практика — критерий истины! Попробуем и посмотрим, что получилось.
class Program
{
static void Main(string[] args)
{
var instance = new { Name = "Alex", Age = 27, Id = new { Number = 123 } };
var allTypes = Assembly.GetExecutingAssembly().GetTypes();
foreach (var t in allTypes)
{
var nestedTypes = t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
Console.WriteLine($"Name: {t.FullName}, nested types: {nestedTypes.Length}");
}
}
}
Результат:
Name: <>f__AnonymousType0`3, nested types: 0
Name: <>f__AnonymousType1`1, nested types: 0
Name: NestedAnonymous.Program, nested types: 0
Таким образом, для компилятора второй анонимный тип ничем не отличается от первого, вложенных типов в программе нету. Этого и стоило ожидать: ведь когда мы пишем var instance = new { List = new List<int>() };
, мы же не ожидаем, что List<int>
окажется вложенным типом анонимного типа?
Для сравнения, положим ещё один вложенный тип:
class Program
{
class Nested { }
static void Main(string[] args)
{
var instance = new { Name = "Alex", Age = 27, Id = new { Number = 123 } };
var allTypes = Assembly.GetExecutingAssembly().GetTypes();
foreach (var t in allTypes)
{
var nestedTypes = t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
Console.WriteLine($"Name: {t.FullName}, nested types: {nestedTypes.Length}");
}
}
}
Получаем такой вывод:
Name: <>f__AnonymousType0`3, nested types: 0
Name: <>f__AnonymousType1`1, nested types: 0
Name: NestedAnonymous.Program, nested types: 1
Name: NestedAnonymous.Program+Nested, nested types: 0
Мы видим, что у Program
появился вложенный тип, и что имя вложенного типа содержит имя объемлющего типа, отделённое плюсиком. (Это, разумеется, внутренняя подробность имплементации анонимных типов компилятором в поставке MSVC 2015, другие компиляторы могут делать это по-другому.)
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Хотел бы узнать, как в консоле реализовать генерацию, движение и стрельбу противников
Пишу мини-игру на Console C#Для более красивого отображения хочется убрать полосы прокрутки снизу и сбоку консоли