隐型局部变量 C# 引入了一个叫做var的新关键字这个关键字允许开发者建立一个变量但不必明确它的类型例如用var说明一个字符串就像这样
varmyData = This is my data;
注意这里并没有提到myData变量是一个字符串而C# 却要求这一点
虽然var允许您建立隐含的类型它并没有降低C#浓厚的类型特征var关键字只有在建立变量时有用一旦您建立变量并且确定它的类型以后就不能再用var来改变一个变量的类型
例如这段代码没有作用
varmyDate = DateTimeNow;
myDate = Hello;
使用var关键字还会产生一个有趣的结果它可以帮助开发者减少建立变量时的代码输入例如在C# 中建立一个Customer对象需要输入以下代码
Customer myCustomer = new Customer();
使用新的var关键字则只要输入
varmyCustomer = new Customer();
var关键字的另一个特点在于使用它可以避免改变一个返回某个类型对象的方法调用例如在C# 中如果您需要调用一个返回Customer对象的方法您应该编写以下代码
Customer myCustomer = GetByName(Zach);
如果某个时候GetByName方法返回一个不是Customer的对象这段代码就无法编译但是如果应用var关键字您就不用担心GetByName返回的对象类型
varmyData = GetByName(Zach);
现在因为应用了var关键字GetByName方法能够进行改变返回一个Person对象这个方法调用也依然有效
extension方法
在C#中您不能继承和扩充用访问标识符标记为封装的类型但在C# 中extension方法允许您扩充任何类甚至是标记为封装的类例如如果希望添加一个NoSpaces()方法到字符串类中我们要定义一个类似列表A中的extension方法
列表A
namespaceMyExtensionMethods
{
public static class Extension
{
public static void NoSpaces(this string data)
{
return dataReplace( );
}
}
}
在一个类中导入这个extension方法时开发者就能够对这个类包含的任何字符串调用NoSapces()方法
extension方法的第一个参数决定extension方法的有效类型在这种情况下这个字符串数据(this string data)表明extension方法适用于字符串类如果extension方法以这个对象数据(this object data)为第一个参数则说明这个方法对每个对象有效
要表明您希望导入extension方法只需在它们的命名空间中包括一个using指令例如要应用上面说明的方法需要在类文件中包括一个using MyExtensionMethods指令(列表B)
列表B
usingMyExtensionMethods;
namespace MyNamespace
{
public class MyClass
{
public MyClass()
{
string data = this is my data;
//nospaces will contain thisismydata
string nospaces = dataNoSpaces();
}
}
}
注意extension方法的优先度比instance方法低因此如果instance方法和extension方法有同样的签名则应执行instance方法
对象初始化器
在C# 中开发者认为建立许多构造器来设定某个属性值为对象初始化过程下面是一个例子 类访问Customer方法
Customer myCustomer = new Customer(Zach Smith);
Customer类构造器
public Customer(string firstName string lastName) : this()
{
thisFirstName = firstName;
thisLastName = lastName;
}
public Customer()
{}
C# 介绍了一个初始化对象的新方法它允许您在初始化对象时设定任何属性值例如在C# 中上面的代码块可以写成
类访问Customer方法
Customer myCustomer = new Customer{FirstName = Zach LastName = Smith };
Customer类构造器
public Customer()
{}
在C# 代码中没有与初始化对象对应的构造器这样开发者就不用为每组需要设定的属性建立不同的构造器
这样产生的另外一个效果是代码变得更容易阅读了例如虽然我们清楚知道下面的代码对一个Car对象进行了初始化但我们并不清楚其中变量的作用
Car car = new Car( );
一眼看来下面这行代码更易阅读尽管我们必须输入更多代码
Car car = new Car { WheelDiameter = WheelWidth = Horsepower = };
匿名类型
C# 引入了匿名方法C# 推出匿名类型匿名类型与匿名方法类似它们都是以嵌入方式建立并没有正式的名称在建立一个匿名类型您必须组合上述对象初始化器和隐型局部变量两个概念下面是一个匿名类型的例子
varmyType = new { Length = Width = };
匿名类型的范围与任何其它变量的范围相同例如下面代码块中的cobra实例仅仅在Speed函数块中有效
private void Speed()
{
var cobra = new { Horsepower = Torque = };
}
如果一个匿名类型被初始化而另一个匿名类型位于范围域中并且它们的签名相同第二个类型将自己占用第一个类型的类型例如在下面这段代码中cobra和mustang都是匿名类型并且可以彼此设定
private void Speed()
{
var cobra = new { Horsepower = Torque = };
var mustang = new { Horsepower = Torque = };
mustang = cobra; //or you could say cobra = mustang
}
LINQ
在之前的C#版中开发者应用许多不同的查询语言来访问不同的数据源例如要查询一个XML文件开发者会使用XPath要查询一个SQL数据库开发者将使用SQL在过去这种方法十分有效并且现在仍然是访问各种数据的主要方法但是这种方法具有一些缺点 一个显着的缺点在于开发者必须以一种不同的语言而非他们当前使用的语言(如SQL或XPath)来编写查询代码另一个缺点是在执行某些查询语言如SQL时开发者必须编写映射代码将查询结果转化为可用的C#业务对象
C#推出一种称之为语言集成查询(LINQ)的新方法应用LINQ开发者可以编写出能够搜索任何IEnumerable<T>数据源的代码所以除了应用TSQL访问MS SQL数据库应用XPath访问XML文件外他们还可以应用LINQ
下面的代码(列表C)是一个LINQ查询的例子它返回所有OrderCount大于的顾客
列表C
using System;
using SystemQuery;
using SystemCollectionsGeneric;
public class SampleClass
{
static void Main()
{
List<Customer> customers = GetCustomers();
//Write our query to retrieve customers who have more than
// orders
IEnumerable<Customer> queryResult = from customer in customers
where customerOrderCount >
orderbycustomerID
select customer;
}
}
与SQL或XPath不同LINQ查询用C#而非第三方语言编写这样查询就不会出现类型问题开发者也就没有必要编写映射代码把查询返回的数据转化成C#对象而由LINQ API自动处理映射
基本上在ORM解决方案中LINQ对象用途很大同样它的范围也非常广泛有大量MSDM信息描述了它的功能欲了解更多信息请访问LINQ主页