知识点:C# 拓展方法

知识点:C# 拓展方法

拓展方法可以在不修改类的前提下对类的功能进行拓展,使用的感受就是是在类的外部对类直接添加了可执行的方法,不需要进入类的内部编写添加的方法,也不需要重新编译该类。拓展方法的实现是静态类和静态方法,但使用拓展方法时可以和其他的类实例方法一样被调用。

定义拓展方法的语法:

public class MyClass
{
    public string name = "My Class";
    private int value = -1;
}

public static class MyExtansion 
{
    public static void ShowName(this MyClass target)
    {
        Console.WriteLine(target.name);
    }
}

类MyClass中定义了属性但并无任何方法,静态变量中的静态方法通过在参数中使用this标识该方法为参数MyClass类型的拓展方法。拓展方法ShowName简单地输出一个MyClass类型的属性name。当MyExtansion类在当前代码的作用域有效时,使用拓展方法ShowName就和使用MyClass自己的方法一样:

	MyClass mc = new MyClass();
	mc.ShowName();								// 输出“My Class”

通过这样的方式,便能在不修改MyClass类的前提下,对它的功能进行拓展,每次拓展只需要修改和维护外部的静态方法。当然,也可以通过传统的调用静态方法的途径调用ShowName方法:

	MyExtansion.ShowName(mc);					// 和 mc.ShowName(); 是一样的

而官方文档对拓展方法的描述也称,对拓展方法的调用实际上在编译器编译生成IL(中间语言)时,会将其转为对静态方法的调用。我们使用实例方法语法调用拓展方法本质上是一种语法糖,拓展方法并不是真正属于这个类的方法。所以类的封装性并没有被破坏掉,作为外部静态方法的拓展方法并不能直接访问到类的非Public属性:

public static class MyExtansion 
{
    public static void ShowValue(this MyClass target)
    {
        Console.WriteLine(target.value);		// 将会报错 value是MyClass的私有属性
    }
}

还有值得注意的一点是,拓展方法并不能重写或覆盖类本身的方法,如果有拓展方法和类自身的一个方法签名完全相同,则拓展方法将被忽略。

编译时,扩展方法的优先级总是比类型本身中定义的实例方法低。 换句话说,如果某个类型具有一个名为 Process(int i) 的方法,而你有一个具有相同签名的扩展方法,则编译器总是绑定到该实例方法。 当编译器遇到方法调用时,它首先在该类型的实例方法中寻找匹配的方法。 如果未找到任何匹配方法,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到的第一个扩展方法。

应用场景

想象这样一个场景,一个类被多个类继承,当它们被编写完毕打包为程序集,这时候想要对父类拓展功能,就只能进入父类中为实现新的方法以提供调用,然后重新打包程序集。另一个场景是有一个接口,该接口被多个不同的类实现,这时候想要对这个接口拓展功能,且这个功能对于所有实现类来说都是一样的,这时将不得不在接口中定义新的方法,然后在多个实现类中实现它。
而使用拓展方法将会省心省力得多,只需要将拓展方法的this部分定义为需要拓展的类或接口,接下来就可以方便优雅地拓展功能而不需要修改到原来部分的代码。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值