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

 

posted @ 2022-12-05 12:14  末叶da  阅读(32)  评论(0)    收藏  举报