参考: 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-\.]+@([\w-]+\.)+[\w-]{2,4}$");
return regex.IsMatch(s);
}
bool isValid = "so@mmas.com".IsValidEmailAddress();
添加的方法将会出现在 IntelliSense 中:
(来源:scottgu.com)
关于扩展方法的实际用途,你可以在不派生新类的情况下向一个类中添加新方法。
看一下以下示例:
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的方法。要获得平均值,您需要调用average
方法,因为它属于extended
类:
Extended ex = new Extended();
Console.WriteLine(ex.average());
即使您无法访问原始源代码,也可以向某些内容添加方法。 让我们考虑一个例子来解释这一点:
假设我有一只狗。 所有狗 - 所有类型为狗的动物 - 都会做某些事情:
狗能做的所有事情都被称为“方法”。 现在假设OO天堂中的伟大程序员忘记向狗类添加一个方法:FetchNewspaper()。 您希望能够说:
rex.FetchNewspaper(); // or
beethoven.FetchNewspaper();
尽管您无法访问源代码,但仍然可以这样做。
你是如何让你的狗这样做的? 您唯一的解决方案是创建一个“扩展方法”。
(请注意下面第一个参数前面的“this”关键字):
public static void FetchNewsPaper(this Dog familyDog)
{
Console.Writeline(“Goes to get newspaper!”)
}
如果你想让你的狗拿报纸,只需这样做:
Dog freddie_the_family_dog = new Dog();
freddie_the_family_dog.FetchNewspaper();
您可以向一个类添加方法而无需拥有源代码。这非常方便!
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Sub DoSomething(ByVal source As System.Windows.Forms.Form)
'Do Something
End Sub
End Module
扩展方法是一种“编译器技巧”,它允许您模拟向另一个类添加方法的操作,即使您没有该类的源代码。
例如:
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
关键字开头等等)。
扩展方法实际上不会修改它们看起来要扩展的类;相反,编译器会混淆函数调用,以便在运行时正确地调用该方法。但是,扩展方法将适当地显示在 IntelliSense 下拉菜单中,并且您可以像普通方法一样记录它们(如上所示)。
注意:如果已经存在一个具有相同签名的方法,则扩展方法永远不会替换该方法。
扩展方法是一种特殊的静态方法。它允许我们在不修改现有类型的情况下添加方法。 例如,如果您有一个Customer类,并且需要添加一个方法而不修改Customer类,对于这种情况,我们有扩展方法。 请参阅此链接以获取更多示例 https://princesid85.wixsite.com/website/home/you-ve-been-holding-your-pen-wrong-your-entire-life
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
扩展方法是一种技术,通过它我们可以为现有的数据类型添加方法。以下是如何向现有数据类型添加方法的示例。
代码:
public static class ExtensionMethods
{
public static int WordCount(this string str)
{
return str.Split(' ').Count();
}
public static int LongestWord(this string str)
{
return str.Split(' ').Select(x =>
x.Length).OrderByDescending(y =>
y).FirstOrDefault();
}
}
代码:
public static void Main(String[] args)
{
string str = "this is my name punit";
int i = str.LongestWord();
}
要点:
扩展方法类需要是静态的
扩展方法的第一个参数将具有this关键字,该方法也应该是静态的
C#中的扩展方法
什么是扩展方法?
Extension method means Class name and method name are having with Static Key word.
扩展方法使用“this”关键字,第一个签名应该是标识地址,这种类型必须与相同的类型相同,
public static string Meth(this string i,int j)
和
string res = "ae".Meth(num);
粗体部分是标识地址。命名空间应该相同。
为什么我们需要扩展?
我们在许多地方使用相同的函数,之后无法找到为什么在这里使用。因此使用地址标识。静态意味着单个实例。这只能访问静态成员函数。即使如何在静态类中访问非静态类方法?例如:查看“Sal”方法中抛出错误,
static class Emp { public int Sal(int i,int j) { return i * j; } }
仅访问静态成员。和
在该代码之后,我们无法在静态类中为非静态类创建对象。那么如何在静态类中访问非静态方法。因此,我们遵循扩展方法而不是继承。
例如,在此处使用扩展方法添加或甚至功能,
使用 System.Text;
使用 System.Threading.Tasks;
命名空间 Extension_Method { 静态类 Program {
public static string Meth (this string i,int j)
{
if (j % 2 == 0)
{
return "Even";
}
else
{
return "ODD";
}
}
}
class program2
{
static void Main (string [] args)
{
Console. WriteLine ("Enter Integer");
int num = Convert.ToInt32(Console.ReadLine());
string res = "ae".Meth(num);
Console. WriteLine(res);
Console.ReadLine();
}
}
结果:
我想就扩展方法回答一个密封类的问题。
假设您有一个包含重要方法的密封类。现在您想要添加一个新方法。假设这个类来自外部DLL,因此您无法向其中添加新方法。那么你会怎么做?
再举一个例子。假设该类是由您的项目经理或安全专家在应用程序中构建的。您只能通过获得项目经理或安全专家的许可来编辑该类。
您的解决方案可能是从该类中删除Sealed关键字并将其继承到其他类中。然后,在子类(继承此类的类)中,您可以添加新方法。
但是等等->您不能简单地删除Sealed关键字,因为这可能会危及整个应用程序的安全性。我敢打赌,您的项目经理或安全专家永远不会给您那个权限,引用安全问题。
那么在这里可以做什么?
答案是扩展方法,它们可以添加到静态类中,您甚至不需要再触摸密封类。
例如:
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;
}
}
我在一个新的静态类中添加了一个名为Average的公共静态方法。该方法具有使用“this”关键字前缀的主类参数。
现在,要调用Average方法,我使用父封闭类的对象而不是子类的对象。
MyData md = new MyData(3, 4, 5);
double exAverage = md.Average();
/// <summary>
/// External Library Code
/// </summary>
namespace ExternalLibrary
{
public class Calculator
{
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Addition()
{
return Number1 + Number2;
}
public int Subtraction()
{
return Number1 - Number2;
}
}
}
using ExternalLibrary;
using System;
namespace StackOverFlow
{
class Program
{
static void Main(string[] args)
{
Calculator calc = new Calculator()
{
Number1 = 5,
Number2 = 3
};
Console.WriteLine(calc.Addition());
Console.WriteLine(calc.Subtraction());
// Here we want multiplication also. but we don't have access Calculator
// class code, so we can't modify in that.
// In order to achieve this functionality we can use extension method.
Console.WriteLine(calc.Multiplication());
Console.ReadLine();
}
}
/// <summary>
/// Extension Method for multiplication
/// </summary>
public static class CalculatorExtension
{
public static int Multiplication(this Calculator calc)
{
return calc.Number1 * calc.Number2;
}
}
}