当有如下这样类似的情况出现的时候,可以有更好的优化方式来处理,那就是分部方法
1 class PartOld 2 { 3 string name; 4 5 public virtual void OnChangeName(string str) 6 { 7 } 8 9 public string Name 10 { 11 set 12 { 13 //如果该方法没有实现的话,生成的IL 代码也会有调用这样的一个虚方法 callvirt, 造成性能上不必要的损失 14 OnChangeName(value.ToUpper()); 15 name = value; 16 } 17 } 18 }
以上的方式生成如下的IL代码,这里会无谓的去调用一个没有实现的方法,没有意义的:
优化方式:分部方法
1 sealed partial class Part 2 { 3 string name; 4 5 /// <summary> 6 /// 分部方法 7 /// </summary> 8 /// <param name="str"></param> 9 partial void OnChangeName(string str); 10 11 public string Name 12 { 13 set 14 { 15 OnChangeName(value.ToUpper());//如果分部方法没有实现,那么生成的 IL 中不会调用该方法 16 name = value; 17 } 18 } 19 } 20 sealed partial class Part 21 { 22 /// <summary> 23 /// 实现分部方法 24 /// </summary> 25 /// <param name="str"></param> 26 partial void OnChangeName(string str) 27 { 28 if(string.IsNullOrEmpty(str)) 29 { 30 throw new ArgumentException(str); 31 } 32 } 33 }
改进后的IL 代码实现如下:
1. 没有实现分部方法的时候:
2. 实现了分部方法的时候:
通过这样的方式优化后,更加灵活和性能更佳!
关于分部方法,需要注意的是:
1. 只能在分部类或者结构中声明
2. 分部方法返回值始终是 void, 参数不能使用 out 修饰符,这是由于改方法的实现是不确定的,所以不允许有变量接收此返回值,同时out 参数也需要在方法内部初始化,但是方法不一定存在
3. 分部方法默认是private,也只能是private,不需要显示声明
......