linq学习笔记(1):c#3.0新特性(1)
C# 3.0新语言特性在.NET2.0基础上进行了改进,这些改进的功能可以大大简化我们编写程序。我在这里简单记录一下自己所学笔记,也为后面的LINQ学习打下基础。
1. 隐含类型局部变量(Local Variable Type Inference)
C#3.0引进了var这个新关键字,在声明局部变量时可用于替代原先的类型名,即当一个变量声明标识为var类型并且该范围域中没有var名称类型存在,那么这个声明就称为隐含类型局部变量。如下(等同于其下面的注释掉的显式声明):
var为关键字,可以根据后面的初始化语句自动推断类型,这个类型为强类型( 注意区分Javascript中的var)。
初始化语句必须为表达式,不可以为空,且在编译时可以推断类型。因为var是由编译器推断类型的就必须声明的时候赋值,而且不能是null值,并且一旦初始化之后,只可以存储这种类型,如下的写法是错误的:
匿名类型允许定义行内类型,无须显式定义类型。常和var配合使用来声明匿名类型。定义一个临时的匿名类型在LINQ查询句法中非常常见,我们可以很方便的实现对象的转换和投影。看如下代码:
User1和User2结构相同,则可以相互赋值:
C# 3.0给我们带来了自动属性的概念,下面来看一下c#3.0中的自动属性的写法:
代码是不是简洁多了呀。上面这几行简短的代码和我们最初给出的属性形式是等效的,对于其自身不存在逻辑的属性都可以这样来编写,当然也可以继续采用原先的方式,其实在预编译时会将自动属性还原为原先的属性形式,只是这部分工作由编译器来完成,从而减轻了程序员的工作量。在一些情况下,例如你想让这个属性成为只读或者对其写操作进行一些控制,那么你可以在set关键字前面加上访问修饰符,例如:
这个属性就是只读的了。自动属性只能用于简单属性,复杂属性还是老老实实的敲代码吧。
1. 隐含类型局部变量(Local Variable Type Inference)
C#3.0引进了var这个新关键字,在声明局部变量时可用于替代原先的类型名,即当一个变量声明标识为var类型并且该范围域中没有var名称类型存在,那么这个声明就称为隐含类型局部变量。如下(等同于其下面的注释掉的显式声明):
var age = 26;
//int age = 26;
var username = "peida";
//string username = "peida";
var userlist = new[] { "peida", "bamboo", "candana" };
//string[] userlist = new string[3] { "peida", "bamboo", "candana" };
//int age = 26;
var username = "peida";
//string username = "peida";
var userlist = new[] { "peida", "bamboo", "candana" };
//string[] userlist = new string[3] { "peida", "bamboo", "candana" };
var为关键字,可以根据后面的初始化语句自动推断类型,这个类型为强类型( 注意区分Javascript中的var)。
初始化语句必须为表达式,不可以为空,且在编译时可以推断类型。因为var是由编译器推断类型的就必须声明的时候赋值,而且不能是null值,并且一旦初始化之后,只可以存储这种类型,如下的写法是错误的:
var age = 26;
age = "peida";
var Sex;//错误
var NikeName = null;//错误
var Address = { 1, 2, 3 };//错误
age = "peida";
var Sex;//错误
var NikeName = null;//错误
var Address = { 1, 2, 3 };//错误
var声明的仅限于局部变量,不可用于字段。亦可以用于for,foreach,using 等语句中。
数组也可以作为隐含类型。
初始化语句不能是一个自身的对象或者集合初始化器,但是他可以是包含一个对象或者初始化器的一个new表达式。
如果局部变量声明包含了多个声明符,其类型必须相同。
匿名类型允许定义行内类型,无须显式定义类型。常和var配合使用来声明匿名类型。定义一个临时的匿名类型在LINQ查询句法中非常常见,我们可以很方便的实现对象的转换和投影。看如下代码:
var User1 =new {UserID=1, UserName = "peida" ,UserAge=25};
var User2 = new { UserID = 2, UserName = "bamboo", UserAge = 30 };
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User1.UserName, User1.UserAge, User1.UserID);
Console.WriteLine("------------------------------");
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User2.UserName, User2.UserAge, User2.UserID);
Console.WriteLine("------------------------------");
var User2 = new { UserID = 2, UserName = "bamboo", UserAge = 30 };
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User1.UserName, User1.UserAge, User1.UserID);
Console.WriteLine("------------------------------");
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User2.UserName, User2.UserAge, User2.UserID);
Console.WriteLine("------------------------------");
User1和User2结构相同,则可以相互赋值:
User2 = User1;
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User2.UserName, User2.UserAge, User2.UserID);
使用"new[]"关键字来声明数组,加上数组的初始值列表,如下所示:Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", User2.UserName, User2.UserAge, User2.UserID);
var UserArr = new[] { new { UserName = "peida", UserAge = 25, UserID = 1 }, new { UserName = "bamboo", UserAge = 30, UserID = 2 } };
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", UserArr[1].UserName, UserArr[1].UserAge, UserArr[1].UserID);
Console.WriteLine("用户名:{0}, 年龄:{1},编号:{2}", UserArr[1].UserName, UserArr[1].UserAge, UserArr[1].UserID);
可以使用new关键字调用匿名初始化器创建一个匿名类型的对象;匿名类型直接继承自System. Object;匿名类型的成员是编译器根据初始化器推断而来的一些读写属性。
3. 自动属性(Auto-Implemented Properties)
过去我们书写C#类的属性时都是采用如下的方式:
public class Person
{
private int userid;
private int userage;
private string username;
public int UserID
{
get { return userid; }
set { userid = value; }
}
public int UserAge
{
get { return userage; }
set { userage = value; }
}
public string UserName
{
get { return username; }
set { username = value; }
}
}
{
private int userid;
private int userage;
private string username;
public int UserID
{
get { return userid; }
set { userid = value; }
}
public int UserAge
{
get { return userage; }
set { userage = value; }
}
public string UserName
{
get { return username; }
set { username = value; }
}
}
C# 3.0给我们带来了自动属性的概念,下面来看一下c#3.0中的自动属性的写法:
public class Person
{
public int UserID { get; set; }
public int UserAge { get; set; }
public string UserName { get; private set; }
public string Name { get; private set; }
}
{
public int UserID { get; set; }
public int UserAge { get; set; }
public string UserName { get; private set; }
public string Name { get; private set; }
}
代码是不是简洁多了呀。上面这几行简短的代码和我们最初给出的属性形式是等效的,对于其自身不存在逻辑的属性都可以这样来编写,当然也可以继续采用原先的方式,其实在预编译时会将自动属性还原为原先的属性形式,只是这部分工作由编译器来完成,从而减轻了程序员的工作量。在一些情况下,例如你想让这个属性成为只读或者对其写操作进行一些控制,那么你可以在set关键字前面加上访问修饰符,例如:
public string UserName { get; private set; }
这个属性就是只读的了。自动属性只能用于简单属性,复杂属性还是老老实实的敲代码吧。