什么是扩展方法?
回答
扩展方法允许开发新的方法添加到现有的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. AjaxControlToolkit - 扩展 - 什么是“当前”方法?
- 3. 为什么要使用扩展方法?
- 4. 为什么作为扩展方法
- 5. Vue.js“扩展”用法的正确方法是什么?
- 6. 什么是标记扩展?
- 7. Haskell的扩展是什么?
- 8. 什么是file.sc的扩展
- 9. 什么是扩展类?
- 10. 什么是C#后面的扩展方法的设计动机
- 11. 在java中扩展类funcionality的最佳方法是什么?
- 12. 定义这种扩展方法的缺点是什么?
- 13. 扩展Laravel厂商包的最佳方法是什么?
- 14. 构建SQLite FTS扩展为DLL的正确方法是什么?
- 15. 扩展课程功能的最佳方法是什么?
- 16. 什么是扩展HttpWebRequest类的Lib的最佳方法?
- 17. 什么是使JQuery插件可扩展的方法?
- 18. 用重复数字扩展列表的好方法是什么?
- 19. 这种通用扩展方法的目的是什么?
- 20. 你在C#中的“扩展方法”是什么意思?
- 21. 什么是在python中扩展url的最快方法
- 22. 什么是处理图片扩展的正确方法?
- 23. 这个Linq查询的等效C#扩展方法是什么?
- 24. 什么是扩展现有ActiveX/COM组件的正确方法?
- 25. LINQ方法是扩展方法吗?
- 26. 扩展方法
- 27. 什么是扩展方法,为什么我们需要使用它?
- 28. 扩展方法和扩展属性是不好的做法吗?
- 29. 创建通用扩展方法时,我们正在扩展什么?
- 30. AutoMapper展开扩展方法
对于你的后续行动,请参阅下面的答案。 基本上你会创建扩展而不是使用继承。 – 2008-12-31 17:47:01
@汤姆安德森 - 所以创建扩展方法的决定主要基于对源代码的访问?我的情况是 – Developer 2008-12-31 17:49:54
。 另一个实例很容易,而不是从System.Windows.Forms.Form继承,然后添加方法,然后修改我的所有源以使用该基类,我只需编写该扩展,现在所有表单都具有该扩展。 – 2008-12-31 17:52:37