Day9
一、Extension Methods——拓展方法
扩展方法将行为扩展并添加到现有类型,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。当您不能修改您想要增强的类型的来源时,它们特别有用。可以为系统类型、由第三方定义的类型和您自己定义的类型创建扩展方法。扩展方法可以像它是原始类型的成员方法一样被调用。这允许使用用于实现流畅接口的方法链接。
1、Extension methods - overview

 
2、null-checking
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 string nullString = null; 6 string emptyString = nullString.EmptyIfNull(); 7 string anotherNullString = emptyString.NullIfEmpty(); 8 Console.WriteLine(emptyString);//输出“ ” 9 Console.WriteLine(anotherNullString);//输出null 10 Console.ReadKey(); 11 } 12 } 13 public static class StringExtensions 14 { 15 public static string EmptyIfNull(this string text) 16 { 17 return text ?? String.Empty; 18 } 19 public static string NullIfEmpty(this string text) 20 { 21 return String.Empty == text ? null : text; 22 } 23 }
3、Extension methods can only see public (or internal) members of the extended class
扩展方法只是一种语法,实际上并不是它们所扩展的类的成员。这意味着它们不能中断封装——它们只能访问公共的(或在同一程序集、内部中实现时)字段、属性和方法
public class SomeClass { public void DoStuff() { } protected void DoMagic() { } } public static class SomeClassExtensions { public static void DoStuffWrapper(this SomeClass someInstance) { someInstance.DoStuff(); // ok } public static void DoMagicWrapper(this SomeClass someInstance) { someInstance.DoMagic(); // 错误 } }
4、Extension methods for chaining——链的扩展方式
当扩展方法返回与此参数具有相同类型的值时,它可以用于使用兼容的签名“链化”一个或多个方法调用。这对于密封和/或原始类型很有用,如果方法名称读起来像自然的人类语言,则允许创建所谓的“流畅”api。

result的结果依次是:5(初始值)——> 6——>5——>6
下面也是链的一种拓展方式:
1 void Main() 2 { 3 int[] ints = new[] { 1, 2, 3, 4, 5, 6}; 4 int[] a = ints.WhereEven(); 5 //a is { 2, 4, 6 }; 6 int[] b = ints.WhereEven().WhereGreaterThan(2); 7 //b is { 4, 6 }; 8 } 9 public static class IntArrayExtensions 10 { 11 public static int[] WhereEven(this int[] array) 12 { 13 //Enumerable.* extension methods use a fluent approach 14 return array.Where(i => (i%2) == 0).ToArray(); 15 } 16 public static int[] WhereGreaterThan(this int[] array, int value) 17 { 18 return array.Where(i => i > value).ToArray(); 19 } 20 }
5、Extension methods dispatch based on static type——基于静态类型的扩展方法调度
1 { 2 public static void Main() 3 { 4 Derived derived = new Derived(); 5 Base @base = derived; 6 Console.WriteLine(derived.GetName()); 7 Console.WriteLine(@base.GetName()); 8 9 Console.WriteLine(derived.GetNameByExtension()); 10 Console.WriteLine(@base.GetNameByExtension()); 11 } 12 } 13 public class Base 14 { 15 public virtual string GetName() 16 { 17 return "Base"; 18 } 19 } 20 public class Derived : Base 21 { 22 public override string GetName() 23 { 24 return "Derived"; 25 } 26 } 27 public static class Extensions 28 { 29 public static string GetNameByExtension(this Base item) 30 { 31 return "Base"; 32 } 33 public static string GetNameByExtension(this Derived item) 34 { 35 return "Derived"; 36 } 37 }
输出结果
 
二、命名参数
1、Argument order is not necessary——不需要使用参数顺序

2、Named arguments and optional parameters——将已命名的参数与可选的参数组合起来
将已命名的参数与可选的参数组合起来
1 public sealed class SmsUtil 2 { 3 public static bool SendMessage(string from, string to, string message, int retryCount = 5, 4 object attachment = null) 5 { 6 7 } 8 }
上述的SendMessage方法里面有很多的参数。我们直接运用写的话,会比较的麻烦,看起来也不够的美观。例如
此处代码需要多个入参,视觉效果上就很累。
运用此方法可以这样写:
1 var result = SmsUtil.SendMessage(
2 from : "Cihan",
3 to : "Yakar",
4 message : "Hello there!",
5 attachment : new object());
3、Named Arguments can make your code more clear——命名参数可以使您的代码更加清晰
简单对比:
var result = SmsUtil.SendMessage("Mehran", "Maryam", "Hello there!", 12, null); var result = SmsUtil.SendMessage( from: "Mehran", to: "Maryam", message "Hello there!", retryCount: 12, attachment: null);
三、Named and Optional Arguments——命名参数和可选参数
1、Optional Arguments——可选参数

这个地方的结果就是area里面的120乘以width的56。
但是如果加上一个[opotional],这个地方的area结果就是0了,width的默认为0
1 using System.Runtime.InteropServices;
private static double FindAreaWithOptional(int length, [Optional]int width)
{ 2 try 3 { 4 return (length * width); 5 } 6 catch (Exception) 7 { 8 throw new NotImplementedException(); 9 } 10 } 11 area = FindAreaWithOptional(120); //area=0
                    
                
                
            
        
浙公网安备 33010602011771号