什麼是擴展方法?
回答
擴展方法允許開發新的方法添加到現有的CLR類型, 的公共 合同,而無需子類,或 重新編譯的原始類型。
擴展方法幫助混合的 靈活性的「鴨打字」支持 今天 動態語言中流行的性能和編譯時強類型語言 的 驗證。
參考:http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx
下面是一個擴展方法的一個樣品(注意第一參數的this
關鍵字盈):
public static bool IsValidEmailAddress(this string s)
{
Regex regex = new Regex(@"^[\w-\.][email protected]([\w-]+\.)+[\w-]{2,4}$");
return regex.IsMatch(s);
}
現在,上面的方法可以被稱爲直接從任何字符串,像這樣:
bool isValid = "[email protected]".IsValidEmailAddress();
然後
添加的方法也將出現在智能感知:
alt text http://www.scottgu.com/blogposts/extensionmethods/step1.jpg
至於用於擴展方法實際使用,您可以添加新的方法,一類沒有派生新類。
看看下面的例子:
public class Extended {
public int Sum() {
return 7+3+2;
}
}
public static class Extending {
public static float Average(this Extended extnd) {
return extnd.Sum()/3;
}
}
正如你所見,類Extending
是加入一個名爲平均法Extended
類。爲了得到平均,你叫average
方法,因爲它屬於extended
類:
Extended ex = new Extended();
Console.WriteLine(ex.average());
擴展方法的方式爲開發商的「附加」方法,他們無法控制的對象。例如,如果您想爲System.Windows.Forms對象添加一個「DoSomething()」方法,因爲您無法訪問該代碼,您只需爲該表單創建一個擴展方法以下語法。
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Sub DoSomething(ByVal source As System.Windows.Forms.Form)
'Do Something
End Sub
End Module
現在您可以在表單中調用「Me.DoSomething()」。
總之,它是一種向現有對象添加功能而無需繼承的方法。
擴展方法是「編譯器把戲」,讓您可以模擬加方法到另一個類,即使你沒有它的源代碼。
例如:
using System.Collections;
public static class TypeExtensions
{
/// <summary>
/// Gets a value that indicates whether or not the collection is empty.
/// </summary>
public static bool IsEmpty(this CollectionBase item)
{
return item.Count == 0;
}
}
從理論上講,所有集合類現在包括IsEmpty
方法,如果方法沒有項目(前提是你已經包括定義上述類的命名空間),則返回true。
如果我錯過了任何重要的東西,我肯定有人會指出。 (請!)
當然,也有關於擴展方法的聲明(他們必須是靜態的,第一個參數必須由this
關鍵字來preceeded,等等)的規則。
擴展方法實際上並不修改它們看起來正在擴展的類;相反,編譯器會破壞函數調用,以便在運行時正確調用該方法。但是,擴展方法正確顯示在具有獨特圖標的智能感知下拉列表中,並且您可以像正常方法一樣記錄它們(如上所示)。
注:擴展方法從未替代的方法,如果方法已經具有相同簽名存在。
下面是VB.Net中的示例;注意Extension()屬性。將其放置在項目的模塊中。
Imports System.Runtime.CompilerServices
<Extension()> _
Public Function IsValidEmailAddress(ByVal s As String) As Boolean
If String.IsNullOrEmpty(s) Then Return False
Return Regex.IsMatch(email, _
"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")
End Function
這個問題已經回答了,但我想補充一點,這是非常有用的,如果你有是另一個項目內的類型,你不想回到那個項目爲了添加一些功能。我們使用NHibernate併爲我們的數據持久層提供了一個項目,這些人員都希望保持清潔。爲了在這些對象上獲得更好的和可發現的附加方法,我可以使用擴展方法,它真的讓我的一天變得更加美好。
而且,因爲沒有其他人貼吧,這裏有關於它的MSDN一個很好的文章 - http://msdn.microsoft.com/en-us/library/bb383977.aspx
爲什麼我寫另外一個答案?
上述答案太複雜。我猜如果你需要問什麼是擴展方法,你不會真正知道什麼是(i)公共契約,(ii)CLR,(iii)類型,(iv)子類,( v)鴨打字等
讓我們保持它的簡單 - 擴展方法解釋
假如我有一隻狗。狗是一種「類型」的動物。所有的狗 - 類犬的所有動物 - 做某些事情:
- 吃
- WagsTail
- 呼喊
- 震撼爪子等
的東西,狗可以「汪!」這些都是所謂的「方法」。
現在讓我們假設OO天堂的偉大程序員忘了給狗類添加一個方法。假設你想讓你家裏的所有狗做額外的事情:FetchNewspaper。
你要能夠說:
rex.FetchNewspaper(); // or
wolfie.FetchNewspaper(); // or
beethoven.FetchNewspaper();
......即使你沒有訪問源代碼。沃爾夫,雷克斯和貝多芬是你寵物家庭中的狗。
你最近怎樣才能讓你的狗做到這一點?
您將不得不重新編譯。但是你沒有源代碼!如果您沒有源代碼,則無法將該方法添加到代碼中的相關位置。
你唯一的解決方法是創建一個「擴展方法」。
創建擴展方法
(注意:在下面的第一個參數前面的「this」關鍵字):
public static void FetchNewsPaper(this Dog familyDog)
{
ConsoleWriteline(「Goes to get newspaper!」)
}
如果你想你的狗拿到報紙僅僅做到這一點:
Dog freddie_the_family_dog = new Dog();
freddie_the_family_dog.FetchNewspaper();
如果沒有擴展方法,那麼你就不能問Freddie_the_family_dog到FETC h報紙。
我們剛剛做了什麼?
我們增加了一個額外的方法,讓所有的狗都有能力取得報紙。
它是如何工作的?
你只是:(i)打電話給你的狗,和(ii)告訴他取紙。你不能做的就是說「取一張報紙」,而不指定你家裏的哪隻狗應該抓取。
我希望能幫到你。如果您在發表評論時仍有問題,我會盡我所能解釋。
我想我會添加一個更具概念性和較少依賴代碼的解釋。
想象一下福特公司正在推出施工線。您無法進入施工生產線,但您希望所有福特汽車能夠在汽車後部增加一個擾流板(展示時看起來更酷)。你打算怎麼做?在計算世界中,除非你有機會接觸到福特工廠的原始生產線,否則你不能只是把東西拉向福特。那麼現在你可以:輸入擴展方法。
現在你可以做這樣的事情:
Ford hilux = new Ford();
hilux.DisplayRearFoiler(); // you can now do this even though you don't have access to the Ford source code.
你必須創建擴展方法。參考上面的答案。
我想根據密封類回答擴展方法。
假設你有一個密封類包含重要的方法。你現在想要爲它添加一個新的方法。假設這個類來自一個外部DLL,所以你不能添加一個新的方法。你會做什麼 ?
舉另一個例子。假設該類是由項目經理或安全專家構建在您的應用程序中的。只有獲得項目經理或安全專家的許可,才能編輯該課程。
您的解決方案可能是從此類中刪除密封關鍵字,並且 會在其他類中繼承它。然後在子類(繼承這個類)內部,你可以添加你的新方法。
但等待 - >您不能簡單地刪除密封關鍵字,因爲這可能會危及整個應用程序的安全性。我可以打賭你的PM或安全專家永遠不會以安全問題給你這個權限。
那麼在這裏可以做些什麼?
答案是擴展方法它可以添加在一個靜態類,你甚至不需要再觸摸密封類。
例子: -
sealed class MyData
{
private double D1, D2, D3;
public MyData(double d1, double d2, double d3)
{ D1 = d1; D2 = d2; D3 = d3; }
public double Sum() { return D1 + D2 + D3; }
}
static class ExtendMyData
{
public static double Average(this MyData md)
{
return md.Sum()/3;
}
}
我加入了一個名爲平均到一個新的靜態類中的公共靜態方法。該方法的前面帶有'this'關鍵字的主類的參數。
現在要調用Average方法,我使用父級密封類的對象而不是子類。
MyData md = new MyData(3, 4, 5);
double exAverage = md.Average();
希望你找到擴展方法有用。
- 1. 爲什麼Stream.CopyTo不是擴展方法?
- 2. MEF爲什麼ComposePart是擴展方法?
- 3. AjaxControlToolkit - 擴展 - 什麼是「當前」方法?
- 4. 爲什麼作爲擴展方法
- 5. 爲什麼要使用擴展方法?
- 6. Vue.js「擴展」用法的正確方法是什麼?
- 7. Java中擴展方法的實際用法是什麼?
- 8. 什麼是.tt擴展?
- 9. 什麼是file.sc的擴展
- 10. 什麼是擴展類?
- 11. Haskell的擴展是什麼?
- 12. 什麼是標記擴展?
- 13. 擴展稀疏樣式矩陣的方法是什麼?
- 14. 擴展Dict類的正確方法是什麼?
- 15. 什麼是擴展HttpWebRequest類的Lib的最佳方法?
- 16. 擴展Laravel廠商包的最佳方法是什麼?
- 17. 這個lambda方法的擴展代碼是什麼?
- 18. 什麼是擴展Spring Cloud Config Client的正確方法?
- 19. 擴展方法中「T」(TArg0,TEnum,TInt)的含義是什麼?
- 20. 定義這種擴展方法的缺點是什麼?
- 21. 這個Linq查詢的等效C#擴展方法是什麼?
- 22. Linq擴展方法中GROUP INTO的等價物是什麼?
- 23. 什麼是C#後面的擴展方法的設計動機
- 24. 一般地寫擴展名的正確方法是什麼?
- 25. 構建SQLite FTS擴展爲DLL的正確方法是什麼?
- 26. 用codeigniter擴展日曆的最佳方法是什麼?
- 27. 擴展課程功能的最佳方法是什麼?
- 28. 什麼是在python中擴展url的最快方法
- 29. 以下linq擴展方法的好名字是什麼?
- 30. 你在C#中的「擴展方法」是什麼意思?
對於你的後續行動,請參閱下面的答案。 基本上你會創建擴展而不是使用繼承。 – 2008-12-31 17:47:01
@湯姆安德森 - 所以創建擴展方法的決定主要基於對源代碼的訪問?我的情況是 – Developer 2008-12-31 17:49:54
。 另一個實例很容易,而不是從System.Windows.Forms.Form繼承,然後添加方法,然後修改我的所有源以使用該基類,我只需編寫該擴展,現在所有表單都具有該擴展。 – 2008-12-31 17:52:37