Рассмотрим это:
var me = new { FirstName = "John", LastName = "Smith" };
Это прекрасно, как мы можем это сделать:
Console.WriteLine("{0} {1}", me.FirstName, me.LastName);
Однако мы не можем этого сделать:
public T GetMe()
{
return new { FirstName = "John", LastName = "Smith" };
}
потому что мы не знаем тип T.
Мы могли бы сделать это:
public object GetMe()
{
return new { FirstName = "John", LastName = "Smith" };
}
но тогда нам нужно будет проверить свойства объекта, используя отражение, чтобы получить к ним доступ:
var p = new Prog();
object o = p.GetMe();
Type t = o.GetType();
foreach (var prop in t.GetProperties())
{
Console.WriteLine(prop.Name + ": " + prop.GetValue(o, null));
}
Однако как насчет того, можно ли назвать анонимный тип, как мы его определяем? Конечно, это уже не было бы анонимным, однако оно было бы более кратким и содержательным, чем обычное определение класса.
Рассмотрим это:
public Person GetMe()
{
return new public class Person { FirstName = "John", LastName = "Smith" };
}
Преимущество заключается в том, что тогда было бы возможно вернуть результат сложного запроса Linq из метода без необходимости явно определять класс.
Рассмотрим этот относительно сложный запрос Linq:
List<int> list = new List<int>();
var query = from number in list
select
new
{
Number = number,
Square = number*number,
Absolute = Math.Abs(number),
Range = Enumerable.Range(0, number)
};
Вместо определения такого класса:
public class MyNumbers
{
public int Number { get; set; }
public int Square { get; set; }
public int Absolute { get; set; }
public IEnumerable<int> Range { get; set; }
}
чтобы вернуть переменную запроса из метода, который мы могли бы вместо этого сделать:
List<int> list = new List<int>();
return from number in list
select new public class MyNumbers
{
Number = number,
Square = number*number,
Absolute = Math.Abs(number),
Range = Enumerable.Range(0, number)
};