对象初始值 为解决这一问题,即将发布的“Orcas”版本提供了一种被称为对象初始值的 C# 语言功能。对象初始值主要允许在单一表达式中为多个属性或字段赋值。例如,创建对象的常见模式是:
Customer customer = new Customer(); customer.Name = “Roger”; customer.Address = “1 Wilco Way”; |
此时,Customer 没有可以接受名称和地址的构造函数;但是存在两个属性,即 Name 和 Address,当创建实例后即可设置它们。对象初始值允许使用以下语法创建相同的结果:
Customer customer = new Customer() { Name = “Roger”, Address = “1 Wilco Way” }; |
在我们前面的 CustomerTuple 示例中,我们通过调用其构造函数创建了 CustomerTuple 类。我们也可以通过对象初始值获得同样的结果:
var locals = customers .Where(c => c.ZipCode == 91822) .Select(c => new CustomerTuple { Name = c.Name, Address = c.Address }); |
请注意,对象初始值允许省略构造函数的括号。此外,字段和可设置的属性均可在对象初始值的主体内部进行赋值。
我们现在已经拥有在 C# 中创建查询的简洁语法。尽管如此,我们还有一种可扩展途径,可通过扩展方法以及一组本身非常有用的语言功能来添加新的运算符(Distinct、OrderBy、Sum 等)。
语言设计团队现在有了数种可赖以获得反馈的原型。因此,我们与许多富于 C# 和 SQL 经验的参与者组织了一项可用性研究。几乎所有反馈都是肯定的,但明显疏忽了某些东西。具体而言,开发人员难以应用他们的 SQL 知识,因为我们认为理想的语法与他们擅长领域的专门技术并不很符合。
查询表达式 于是,语言设计团队设计了一种与 SQL 更为相近的语法,称为查询表达式。例如,针对我们的示例的查询表达式可如下所示:
var locals = from c in customers where c.ZipCode == 91822 select new { FullName = c.FirstName + “ “ + c.LastName, HomeAddress = c.Address }; |
查询表达式是基于上述语言功能构建而成。它们在语法上,完全转换为我们已经看到的基础语法。例如,上述查询可直接转换为:
var locals = customers .Where(c => c.ZipCode == 91822) .Select(c => new { FullName = c.FirstName + “ “ + c.LastName, HomeAddress = c.Address }); |
查询表达式支持许多不同的“子句”,如 from、where、select、orderby、group by、let 和 join。这些子句先转换为对等的运算符调用,后者进而通过扩展方法实现。如果查询语法不支持必要运算符的子句,则查询子句和实现运算符的扩展方法之间的紧密关系很便于将两者结合。例如:
var locals = (from c in customers where c.ZipCode == 91822 select new { FullName = c.FirstName + “ “ + c.LastName, HomeAddress = c.Address}) .Count(); |
在本例中,查询现在返回在 91822 ZIP Code 区居住的客户人数。
通过该种方法,我们已经设法在结束时达到了开始时的目标(我对这一点始终觉得非常满意)。下一版本的 C# 的语法历经数年时间的发展,尝试了许多新的语言功能,才最终到达近乎于 2004 年冬提议的原始语法的境界。查询表达式的加入以 C# 即将发布的版本的其他语言功能为基础,并促使许多查询情况更便于具有 SQL 背景的开发人员阅读和理解。
查阅关于
VS2008 的全部文档