【发布时间】:2009-03-17 02:19:12
【问题描述】:
考虑一下:
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)
};
【问题讨论】:
-
当您开始在其他情况下使用 MyNumbers 时,这会变得非常难看。如果您使用跨方法边界的类型,则如果该类型未按照您的建议内联声明,则该类型更易于维护和阅读。
-
对spoon16的评论+1。
-
公平点虽然我认为你可以在编译器中加入一些智能来缓解这些问题。
-
我认为让它不丑的关键是使用单独的语法来命名类型,而不是使用创建值的语法。示例见我的帖子。
-
老实说,我在阅读标题行时差点把自己拉黑。仔细想想也看不出有多大的好处。
标签: c# .net linq c#-4.0 anonymous-types