C#语法糖之第二篇: 参数默认值和命名参数 对象初始化器与集合初始化器
今天继续写上一篇文章C#4.0语法糖之第二篇,在开始今天的文章之前感谢各位园友的支持,通过昨天写的文章,今天有很多园友们也提出了文章中的一些不足,再次感谢这些关心我的园友,在以后些文章的过程中不断的完善以及自我提高,给各位园友们带来更好,更高效的文章。
废话就说到这里,下面正式进入我们的今天的C#4.0语法糖,今天给大家分享一下参数默认值、命名参数、对象初始化器和集合初始化器。
参数默认值和命名参数:方法的可选参数是.net 4.0最新提出的新的功能,对应简单的重载可以使用可选参数和命名参数混合的形式来定义方法这样就可以很高效的提供代码的运行效率。设计一个方法的参数的时,可为部分或全部参数分配默认值。调用其方法时,可以重新指定分配了默认值的参数,也可以使用默认值重新指定分配默认值的参数时,可以显式地为指定参数名称赋值,隐式指定的时候,是根据方法参数的顺序,靠c#编译器的推断。
我们用一个现实的例子来说明一下这个问题:比我我们有个这样的需求,有个客户类群体,他们的年龄默认都25岁,但是有些优质客户可以放宽年龄,可以是24岁或者26等等。下面我直接贴一下传统写法的代码:
1 public class Customer
2
3 {
4
5 //构造默认25岁年龄的客户
6
7 public Customer(string CustomerId, string CustomerName)
8
9 {
10
11 this.Age = 25;
12
13 this.CustomerId = CustomerId;
14
15 this.CustomerName = CustomerName;
16
17 }
18
19 //构造不默认年龄的客户
20
21 public Customer(string CustomerId, string CustomerName,int Age)
22
23 {
24
25 this.Age = Age;
26
27 this.CustomerId = CustomerId;
28
29 this.CustomerName = CustomerName;
30
31 }
32
33 public string CustomerId { get; set; }
34
35 public int Age { get; set; }
36
37 public string CustomerName { get; set; }
38
39 }
1 //默认年龄的客户
2
3 Customer customer=new Customer("01","张三");
4
5 Console.WriteLine("Id:"+customer.CustomerId+"名称"+customer.CustomerName+"年龄"+customer.Age);
6
7 Console.ReadLine();
8
9 //指定年龄的客户
10
11 Customer customerEx = new Customer("01", "张三",26);
12
13 Console.WriteLine("Id:" + customerEx.CustomerId + "名称" + customerEx.CustomerName + "年龄" + customerEx.Age);
14
15 Console.ReadLine();
输出效果:
我们从以上代码可以看出如果名称需要默认值时还需要编写一个重载方法,这样一来代码就越来越多,代码的可读性也会慢慢便复杂。
这时候我们在把C#4.0的语法糖亮出来,呵呵。
1 public class Customer
2
3 {
4
5 public Customer(string CustomerId, string CustomerName,int Age=25)
6
7 {
8
9 this.Age = Age;
10
11 this.CustomerId = CustomerId;
12
13 this.CustomerName = CustomerName;
14
15 }
16
17 public string CustomerId { get; set; }
18
19 public int Age { get; set; }
20
21 public string CustomerName { get; set; }
22
23 }
调用代码
2 Customer customer=new Customer("01","张三");
3 Console.WriteLine("Id:"+customer.CustomerId+"名称"+customer.CustomerName+"年龄"+customer.Age);
4 Console.ReadLine();
5 //指定年龄的客户
6 Customer customerEx = new Customer("02", "张三",27);
7 Console.WriteLine("Id:" + customerEx.CustomerId + "名称" + customerEx.CustomerName + "年龄" + customerEx.Age);
8 Console.ReadLine();
输出结果
输出结果:
以上输出结果可以看出效果是一样的,但是简化了一个重载方法,代码的阅读性也增强了,这就是参数默认值的魅力支出。
但是它也有它的缺点,我们在看看使用它是需要注意的地方:
1、可以为方法和有参属性指定默认值
2、有默认值的参数,必须定义在没有默认值的参数之后
3、默认参数必须是常量
4、ref 和 out参数不能指定默认值
对象初始化器:
我们在写一些实体类的时候,我们往往在写构造方法的时候思考很长时间,除了一个无参构造器外还在想需要写几个构造器呢?哪些参数是需要初始化的。现在你再也不需要为这事烦恼了。语法糖为你提供了对象集合初始化器,在这里通过代码对比一些这两种写法的区别和内在的关联。
1 Customer customer=new Customer();
2
3 customer.CustomerId = "001";
4
5 customer.CustomerName = "李四";
6
7 customer.Age = 25;
8
9 Console.WriteLine("Id:"+customer.CustomerId+"名称"+customer.CustomerName+"年龄"+customer.Age);
10
11 Console.ReadLine();
12
13 //对象初始化器
14
15 Customer customerEx = new Customer
16
17 {
18
19 CustomerId = "002",
20
21 CustomerName = "张三",
22
23 Age = 24
24
25 };
26
27 Console.WriteLine("Id:" + customerEx.CustomerId + "名称" + customerEx.CustomerName + "年龄" + customerEx.Age);
28
29 Console.ReadLine();
输出结果:
输出结果:
从效果上看是都一样,但是通过对象初始化器代码比较简洁,让程序员少些很多代码。
我们再通过反编译工具来看一下对象初始化器和传统的初始化有什么关联的地方。
编译器代码如下:
1 private static void Main(string[] args)
2 {
3 Customer customer = new Customer {
4 CustomerId = "001",
5 CustomerName = "李四",
6 Age = 0x19
7 };
8 Console.WriteLine(string.Concat(new object[] { "Id:", customer.CustomerId, "名称", customer.CustomerName, "年龄", customer.Age }));
9 Console.ReadLine();
10 Customer customer2 = new Customer {
11 CustomerId = "002",
12 CustomerName = "张三",
13 Age = 0x18
14 };
15 Console.WriteLine(string.Concat(new object[] { "Id:", customer2.CustomerId, "名称", customer2.CustomerName, "年龄", customer2.Age }));
16 Console.ReadLine();
17 }
集合初始化器:从编译器代码中可以看出这两种代码效果是一样的对象初始化器在编译器内部调用类默认无参构造函数,所以初始化对象也必须有无参构造函数才可以,这一点跟传统的对象初始化是一致的。
通过上面的对象初始化器我们有个大体的了解了,所以集合初始化器也很自然的出来了,从下面的代码比较一下:
1 Customer customer = new Customer();
2
3 customer.CustomerId = "001";
4
5 customer.CustomerName = "张三";
6
7 customer.Age = 25;
8
9 Customer customer2 = new Customer();
10
11 customer.CustomerId = "002";
12
13 customer.CustomerName = "李四";
14
15 customer.Age = 30;
16
17 // 传统方式
18
19 List<Customer> list=new List<Customer>();
20
21 list.Add(customer);
22
23 list.Add(customer2);
24
25 //集合初始化
26
27 List<Customer> listC=new List<Customer>
28
29 {
30
31 new Customer{CustomerId = "001",CustomerName = "张三",Age = 25},
32
33 new Customer{CustomerId = "002",CustomerName = "李四",Age = 30}
34
35 };
编译器编译效果如下:这些代码可以看出传统的方式比较繁琐,下面的就用几行代码实现跟传统方式一样的效果。
1 private static void Main(string[] args)
2
3 {
4
5 Customer customer = new Customer {
6
7 CustomerId = "001",
8
9 CustomerName = "张三",
10
11 Age = 0x19
12
13 };
14
15 Customer customer2 = new Customer();
16
17 customer.CustomerId = "002";
18
19 customer.CustomerName = "李四";
20
21 customer.Age = 30;
22
23 new List<Customer> { customer, customer2 };
24
25 List<Customer> list3 = new List<Customer>();
26
27 Customer item = new Customer {
28
29 CustomerId = "001",
30
31 CustomerName = "张三",
32
33 Age = 0x19
34
35 };
36
37 list3.Add(item);
38
39 Customer customer4 = new Customer {
40
41 CustomerId = "002",
42
43 CustomerName = "李四",
44
45 Age = 30
46
47 };
48
49 list3.Add(customer4);
50
51 List<Customer> list2 = list3;
52
53 }
以上这些可以总结出其实语法糖不是什么新语法,只不过是把以前一些传统方式的代码交给编译器来实现,以便给程序员带来方便,让程序员代码更简单,代码结构更清晰,所以我个人比较推荐使用。其中原因我在这里就不多讲了。
以上这些观点仅凭代表我个人想法!