C#3 分部方法,簡單標記一下
如果我問你,如果一個普通的類實現了一個介面方法,但是這個類的例項卻訪問不到這個介面的方法,這種情況你遇到過嗎?有時候,你可能在使用分部方法時就會發現這麼一個現象。
C#3 中出現了 “分部方法” ,工作了好幾年一直沒用過,可能不咋實用,也有可能是工作中沒有遇到這種場景,分部類倒是用了不少。最近看了一下,內容簡單,標記一下。
我們 分部方法 和分部類有點類似的是 也是使用的關鍵字 partial ,不過不同的是 部分方法 不能有訪問修飾符 (像public) 或者 virtual ,abstract,override,new,sealed,extern 。
而分部類是沒有這個限制。那麼你應該會想這個方法,是會像介面中定義的沒法帶修飾符方法一樣 天生是公用的, 還是像普通類中 是私有的呢,我迫不及待的做了個程式碼,結局傾向了後者。
//檔案1中
public partial class People { public People(string arg) { Speak($"我被構造了,帶著{arg}"); } partial void Speak(string paramStr); }
//檔案2中
public partial class People { partial void Speak(string paramStr) { Console.WriteLine($"收到引數{params}"); } }
測試
class Test { static void Main() { People p= new People("2019到了"); //p.Speaks("Hello");訪問不到 Console.ReadKey(); } }
上面是我們的使用例子,部分方法 限制了我們的方法不能有返回值,只能是void的方法,且不能獲取out引數,它必須是私有的,可以是靜態的或者泛型。
檔案1中 分部方法 的申明和抽象方法相同,只提供了partial修飾符的簽名而沒有實現,以分號結尾。我們分析檔案1中的IL程式碼,發現建構函式中沒有任何痕跡。
接下來,我們看下如果定義介面,然後實現的時候使用分部方法呢。
public interface IPeople { void Speaks(); }
//檔案1
public partial class People:IPeople { partial void Speaks(); }
//檔案2
public partial class People : IPeople//介面可寫可不寫 { void IPeople.Speaks() { Console.WriteLine("哎呀,2019都來了"); } }
我們發現 實現介面需要顯式實現。然後我們呼叫看看:
class Test { static void Main() { People p2 = new People(); // p2.Speaks();訪問不到 }
p2訪問不到實現的介面方法。當然,如果再定義一個子類,子類的例項也是訪問不到的。那麼怎麼才能訪問到呢,你一定會這麼寫:
class Test { static void Main() { IPeople p1 = new People(); p1.Speaks(); // 完全ok }
所以你總的感覺下來,這個東西限制還是蠻大的。這個特性特別適用那些自動生成程式碼和手動寫程式碼一起互動場景。概況的說,C#3的分部方法讓生成程式碼可以和手寫程式碼以一種豐富的方式進行互動,而不會產生任何效能上的損失,可以說是C#2分部類一種自然的延續。