CSS

[Extension Method] 什麼是擴張方法??

ExtensionMethod

什麼是Extension Method?


Extension Method可以將方法給"加"在現有的Class上:

舉例來說:
String.IsNullOrEmpty("Hello Ext");
有時候我會覺得這樣看起來有點不直覺...這時候就可以使用Extension Method來改寫,
將IsNullOrEmpty給"加"在string物件之上:
public static class StringExtensions{
    public static bool IsNullOrEmpty(this string content){
        return String.IsNullOrEmpty(content);
    }
}
string hello = "Hello Ext"
hello.IsNullOrEmpty();

...好吧,我承認這個例子有點無聊
不過Extension Method就像這樣,可以宣告靜態方法,並於compile時將這些方法附加於物件
而不需要修改物件的原始碼或是使用繼承關係
就像是動態語言的"Duck Typing",可以將行為附加在已經有的class上面.

How to use?

C#:
1.將Extension Method宣告為靜態class以及靜態方法
2.第一個參數為this + 要附加的物件: IsNullOrEmpty(this string content)

VB
1.import System.Runtime.CompilerService
2.宣告Module,宣告靜態方法(shared),第一個參數為要附加的物件:
3.於方法前加入extension標籤: <Extension()>

Notice:

1.當extension Method與物件本身的方法衝突時,永遠是本體優先
2.可繼承,影響到所有繼承的物件

那麼...為什麼要用Extension呢?

我的看法是,它可以很直覺化的將行為給附加在沒有原始碼,或是系統提供的物件上
舉一個專案上碰到的例子來說:
Response.setHeader( "Pragma", "no-cache" );
Response.addHeader( "Cache-Control", "no-cache" );
Response.setDateHeader("Expires", 0);
是一段寫入取消快取的code,用extract function可以變成:
NoCache(Response);
但如果還有別的頁面要使用NoCache這個方法,NoCache要移到哪裡呢?
要獨立為靜態方法,還是抽出到base class呢?
Extension Method提供了一個最直覺的寫法:
Response.NoCache();

物件的操作與物件本身合為一體,只有Beautiful這個字可以形容了.

when not to?


在extension之外可以直接修改程式時,應該refactor away from extension method
在時常變更,或有繼承,多型關係的class最好不要使用,也無法附加到Static Class上
另外,如果實作於介面上:
1.會影響到每個實作介面的class
2.如果實作複數介面有可能會衝突

Extention Method Library


.NET本身就有一些物件是以Extension Method來提供擴充功能的,例如說一些LINQ方法,datatable的LINQ對應等等

Extention Method Library提供更多物件的擴充功能

像是int可以使用ruby like的 .times語法
4.times( (n) => Console.Writeln(n +" Times"); );

還有Session可以使用.Get<T>來指定型別
.Ensure<T>來確保不會拿到null值等等方便的擴張功能.

No comments:

Post a Comment