1.隐式类型化本地变量
2.自动属性
3.对象初始化器和集合初始化器
4.匿名类型
5. 分部方法
6.扩展方法
7.Lambda和表达式树
8.查询表达式
1.隐式类型化本地变量
在一个隐式类型化的本地变量和声明中,本地变量类型的声明过程是由使用的表达式初始化变量来推断的。当一个本地变量声明标示为var作为类型并且没有var类型名称在范围内,那么这个声明被视作隐式类型化的本地变量声明。
Code
var i = 5; = int i = 5;
var s = "Hello"; =string s = "Hello";
var d = 1.0; =double d = 1.0;
var numbers = new int[] {1, 2, 3}; =int[] numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>(); =Dictionary<int,Order> orders = new Dictionary<int,Order>();
var x;//错误
var y = null;//错误
var z = { 1, 2, 3 };//错误
*声明者必须包含一个构造者。
*这个构造器必须是一个表达式。这个构造器不能够是一个对象或者构造器集合的自身,但是它可以是一个新的包含一个对象 或者构造器集合的表达式。
*在编译时刻构造器表达式的类型不能为null类型。
*如果本地变量声明包含多种构造器,那么构造器必须都具有相同的编译时类型
*var为关键字,可以根据后面的初始化语句自动推断类型,这个类型为强类型。
*初始化语句必须为表达式,不可以为空。且编译时可以推断类型。一旦初始化之后,只可以存储这种类型。
*var声明的仅限于局部变量,不可用于字段。亦可以用于for,foreach,using 等语句中。 数组也可以作为隐含类型。
*初始化语句不能是一个自身的对象或者集合初始化器,但是他可以是包含一个对象或者初始化器的一个new表达式。
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2.自动属性
自动属性允许你避免手工声明一个私有成员变量以及编写get/set逻辑,取而代之的是,编译器会自动为你生成一个私有变量和默认的get/set 操作。
C#2.0
Code
public class Person
{
private string _Firstname;
private string _Lastname;
private int _age;
public int Firstname
{
get { return _Firstname; }
set { _Firstname= value; }
}
public string Lastname
{
get { return _Lastname; }
set { _Lastname = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
}
C#3.0
Code
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
3.对象初始化器和集合初始化器
*简化我们的代码,让本来几行才能写完的代码一行写完
Code
public class user
{
public string FirstName { get; set; }
public string LastName { get; set; }
public intAge { get; set; }
private int test01 = 25;
internal int test02;
}
class Program
{
static void Main(string[] args)
{
user person = new user { FirstName = "Scott", LastName = "Guthrie", test02 = 56, };
Console.WriteLine(person.test02);
Console.WriteLine(person.Age);
Console.ReadLine();
}
}
Code
C#2.0写法:
User user = new User();
user.Id = 1;
user.Name = "Scott";
user.Age = 22;
C#3.0可以这样写:
User user = new User { Id = 1, Name = "Scott", Age = 22 };
我把二个人加到一个基于泛型的类型为User的List集合中:
List<User> user = new List<User>
{
new User{Id=1,Name="Scott",Age=22},
new User{Id=2,Name="Guthie",Age=25},
};
* 可以和构造函数一起使用
*对象初始化器由一系列成员对象组成,其对象必须初始化,用逗号间隔,使用{}封闭。
* 允许只给部分赋值,允许给internal成员赋值
*对象初始化器实际上利用了编译器对对象中对外可见的字段和属性进行按序赋值。
*对象初始化器可以结合构造函数一起使用,并且构造函数初始化先于对象初始化器执行。
*集合初始化器会对初始化器中的元素进行按序调用ICollection<T>.Add(T)方法。
*注意对象初始化器和集合初始化器中成员的可见性和调用顺序。
*对象与集合初始化器同样是一种编译时技术。
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
4.匿名类型
* C#3.0 允许新的操作符被用来作为匿名对象
* 构造器以建立匿名类型的对象
*可以使用new关键字调用匿名初始化器创建一个匿名类型的对象。
*匿名类型的成员是编译器根据初始化器推断而来的一些读写属性
* 匿名类型是没有名称的类类型,它直接继承于object
匿名类型代码示例:
Code
var p1 = new { Name = "西瓜", Price = 495.00 };
var p2 = new { Name = "苹果", Price = 26.95 };
p1 = p2;//结构相同可以相互赋值
Console.WriteLine("name:" + p1.Name + " price=" + p1.Price);
Console.ReadLine();
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
5. 分部方法
* 分部方法是一些方法,它使轻量级的事件处理成为可行
Code
static void Main(string[] args)
{
int i=3
C.M(i=1)
Console.writeLine(i);
Console.writeLine();
}
partial class C
{
static partial void M(int i); //声明一个分部方法,没有下面的方法时,这句不起作用
static partial void M(int i) //实现方法,有没有这个答案不一样,有为1,没有为3
{
}
}
在定义分部方法时,值得注意的是:
1、分部方法必须声明在分部类型(partial class)中;
2、分部方法使用partial 修饰符;
3、分部方法并不是总有方法体(body,即方法的实现);
4、分部方法必须返回void;
5、分部方法可以是静态的(即使用static 修饰符);
6、分部方法可以包含参数(包括在参数中使用this、ref 和params 修饰符,不支持out 修饰符可以使用ref 修饰符来代替它);
7、分部方法必须是私有方法(private)。
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
6.扩展方法
* 扩展方法(Extension method),可以对现有类功能进行扩充,从而使该类型的实例具有更多的方法(功能)。
* Extension Method仅仅是看起来像是一个类型的方法,但其实质上不是,它更像是静态类型的静态方法,事实上,它确实拥有静态方法所具有的所有功能
* Extension Method的作用域是整个namespace可见的,并且可以通过using namespace来导入其它命名空间中的Extension Method
扩展方法实例代码
Code
static class extension
{
public static void add(this test m)
{
Console.WriteLine("add.");
}
}
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
7.Lambda和表达式树
C#2.0 引入了匿名函数,它允许代码块能够被写成“内联”在代理值所期望的地方。当匿名函数提供功能性编程语言的巨大威力的同时,匿名函数的标记也显得相当的冗长。Lambda表达式提供了更简明的功能性标记来书写匿名函数。
--Lambda表达式书写为一组参数列表,紧接着=>标记,然后跟随某个表达式或声明块。
--Lambda表达式的参数可以是显式的或者隐式的类型。在一个显式类型参数列表中,每个参数的类型都必须显式声明。
--表达式树允许Lambda表达式能够代表数据结构替代表示为执行代码
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
8.查询表达式
* 查询表达式提供了,语言集成化的标记,为了和那些关系型或者等级型查询语言,
例如:SQL和Xquery相类似的查询
* 查询表达式以from语句开始并且以select或者group语句结束
Code
public static void Query()
{
Dictionary<string, int> students = new Dictionary<string, int>();
students.Add("litao", 24);
students.Add("yanghua", 21);
students.Add("zhangchao", 22);
IEnumerable<KeyValuePair<string, int>> queryResult = from student in students
where student.Value <= 23
orderby student.Value descending
select student;
foreach (var student in queryResult)
{
Console.WriteLine(student.Key + " is " + student.Value + " years old.");
}
Console.ReadLine();
}
整理自:MSDNCast