Учтите это:
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)
};