通常,我们想要向一个类型中添加方法,可以通过以下两种方式:
- 修改源代码。
- 在派生类中定义新的方法。
但是以上方法并不是万能的,我们并不能保证拥有一个类型的源码,也并不能保证这个类型可以让我们继承(如结构,枚举,String等等)。但是C#提供了一个办法,那就是扩展方法,使用扩展方法可以直接向现有的类型“添加”方法,无需修改类型的源码,也无需用一个派生类实现方法。
一、什么是扩展方法?
扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。
二、扩展方法结构
- 扩展方法所在的类必须声明为static。
- 扩展方法必须声明为public和static。
- 扩展方法的第一个参数必须包含关键字this,并且在后面指定扩展的类的名称。
三、举例
1.实现一个将string字符串转换为int类型的方法。
/// <summary>
/// 扩展方法
/// </summary>
///
public static class ExpandMethod
{
/// <summary>
/// 将字符串转换为int
/// </summary>
/// <param name="str"></param>
/// <returns>失败返回0</returns>
public static int StringToInt(this string str)
{
int.TryParse(str, out var res);
return res;
}
}
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("2" + 1);
Console.WriteLine("2".StringToInt() + 1);
Console.WriteLine("string".StringToInt());
}
}
输出结果:
21
3
0
2.实现两个数相加
/// <summary>
/// 扩展方法
/// </summary>
///
public static class ExpandMethod
{
/// <summary>
/// 两个数相加
/// </summary>
/// <param name="num"></param>
/// <param name="num2"></param>
/// <returns></returns>
public static int Sum(this int num,int num2)
{
return num + num2;
}
}
public class Program
{
static void Main(string[] args)
{
Console.WriteLine(3.Sum(2));
}
}
输出结果:
5
3.扩展方法与扩展的类型中具有相同的签名
public class MyClass
{
public void MethodA()
{
Console.WriteLine("MyClass.MethodA");
}
public void MethodB()
{
Console.WriteLine("MyClass.MethodB");
}
public void MethodC()
{
Console.WriteLine("MyClass.MethodC");
}
public void MethodD(int num)
{
Console.WriteLine("MyClass.MethodD");
}
}
/// <summary>
/// 扩展方法
/// </summary>
///
public static class ExpandMethod
{
public static void MethodB(this MyClass myClass)
{
Console.WriteLine("ExpandMethod.MethodB");
}
public static string MethodC(this MyClass myClass)
{
return "ExpandMethod.MethodC";
}
public static void MethodD(this MyClass myClass,int num)
{
Console.WriteLine("ExpandMethod.MethodD");
}
public static void MethodE(this MyClass myClass)
{
Console.WriteLine("ExpandMethod.MethodE");
}
}
public class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.MethodA();
myClass.MethodB();
myClass.MethodC();
myClass.MethodD(1);
myClass.MethodE();
}
}
运行结果:
MyClass.MethodA
MyClass.MethodB
MyClass.MethodC
MyClass.MethodD
ExpandMethod.MethodE
通过运行结果可以知道,如果扩展的方法与扩展的类型中具有相同的签名,那么方法永远不会被调用。
四、注意
需要注意的是:
如果扩展的方法与扩展的类型中具有相同的签名,那么方法永远不会被调用。
更多关于扩展方法的可以参考官方文档