C#特性 扩展方法

 更新时间:2020年6月25日 11:33  点击:2079

作为.net程序员,我们每天都要和BCL(Base Class Linbrary)打交道。无疑,BCL做为一个年轻的框架类库,她是成功的,但是还有一些时候我们还是得写一些”Helper”方法来扩展类库,由于我们不能修改类库的源代码,我们只有写一个个的静态类。虽然在使用上也算方便,但作为追求完美的程序员来说总有些不雅。


现在我就碰到这样的事情,前两天奉命写一个从XML文件加载Chart图的设置的方法,从XML加载数据绑定到对象上,这肯定是反射的用武之地了。我经常需要写一些根据对象属性名字来判断这个对象是否有这个属性或者根据属性名获取该属性的值。还是按照平常一样,我很快写了一个PropertyHelper,里面有两个静态方法:HasProperty,GetValueByName。


PropertyHelper.HasProperty(point, "X"),如此的调用也还过得去,不过在C# 3.0微软为我们提供了扩展方法。现在我们可以直接这样调用了point.HasProperty(“X”);看看我是如何实现这个扩展方法的?

public static class PropertyExtension
{
    public static object GetValueByName(this object self, string propertyName)
    {
      if (self == null)
      {
        return self ;
      }
      Type t = self.GetType();
      PropertyInfo p = t.GetProperty(propertyName);
      return p.GetValue(self, null);
    }
}

我给object类型添加了一个扩展方法,在.net里所有的类都继承自object,那所有的类都默认的拥有这个方法了,真方便,呵呵。
注意到和普通的静态方法有何差别?在这个方法的第一个参数前面多了一个this关键字。

扩展方法:

1、方法所在的类必须是静态的
2、方法也必须是静态的
3、方法的第一个参数必须是你要扩展的那个类型,比如你要给int扩展一个方法,那么第一个参数就必须是int。
4、在第一个参数前面还需要有一个this关键字。

按照上面的步骤写你就得到了一个“扩展方法”,你可以像调用这个类的原生方法那样去调用它:

复制代码 代码如下:

string str = "abc";
object len = str.GetValueByName("Length");

好像string类型现在有了GetValueByName这个方法一样,但实际上string并没有这样一个方法。那这又是为什么呢?是我们可爱的编译器在其中做了手脚。为了避开编译器的干扰,我们来直接欣赏MSIL代码:

复制代码 代码如下:

L_0008: ldstr "Length"
L_000d: call object TestLambda.PropertyExtension::GetValueByName(object, string)

从MSIL中我们可以看出,这段代码编译后和调用静态方法没有任何的差别(从call指令来看,这是在调用一个静态方法)。

从这里可以知道扩展方法即可以使用实例调用的方式也可以直接使用静态类调用的方式:

复制代码 代码如下:

str.GetValueByName("Length");
PropertyExtension.GetValueByName(str,"Length");

下面将对扩展方法做一些细节的介绍:
Visual Studio 2008对扩展方法有智能感知的支持,如下图

在方法的图标上有一个与其他的都不相同,他的突变下面还带有一个蓝色的向下的箭头,这就表明这个方法是一个扩展方法。
下面是对编写扩展方法要注意的几个原则(当然,仁者见仁、智者见智,这也是一家之言):

扩展方法有就近原则,也就是如果在你的程序里有两个一模一样的扩展方法,一个和你的使用类是处于同一命名空间里,另外一个处于别的命名空间里,这个时候会优先使用同一命名空间里的扩展方法,也就是说“血缘关系”越近,越被青睐。


很多人看到扩展方法也许眼里冒出金光,以后在设计的时候不管三七二十一,反正可以扩展。还有一些人会对类任意扩展,将以前一些作为”Helper”的方法统统使用扩展方法代替,注意的是扩展方法有“污染性”,所以我觉得在扩展的时候还是想想,是不是值得这样扩展。


在扩展的时候也不要对比较高层的类进行扩展,像我上面对object的扩展我觉得就是不可取的,object是所有类的基类,一经扩展,所有的类都被“污染”了。

发表与2008-07-16
于2008-08-06第一次更新

[!--infotagslink--]

相关文章

  • C#中的扩展方法详解

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。”这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类型的基础上增加一个或多个方法,使用时不需要去修改或编译类型本身的代码。...2020-06-25
  • 用扩展方法优化多条件查询(不定条件查询)

    在我们开发过程中,特别是管理系统的开发,经常会遇到多条件查询(或者叫不定条件查询)的案例,就是提供给User输入的查询条件有多个不同的查询栏位,而且,在实际使用中并不能确定User会使用哪些条件来当做搜索条件...2021-09-22
  • C#特性 扩展方法

    在我们的编程生涯中我们要使用很多很多类库,这些类库有的是我们自己开发的,我们有她的代码,有的是第三方发布的,我们不仅没有他们的代码,连看的机会都没有...2020-06-25
  • c#中的扩展方法学习笔记

    扩展方法能够向现有类型“添加”方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型。下面这篇文章主要给大家介绍了关于c#中扩展方法学习的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2020-06-25
  • 如何利用扩展方法来链式的对MVC 3中的页面进行验证

    虽然扩展方法只是改变了我们写代码的方式,但是如果我们使用得当,可以给我们带来巨大的编码效率的提升接下来介绍通过扩展方法(链式方法)为MVC 3视图添加验证...2021-09-22
  • asp.net中CSharpThinking扩展方法分析

    这篇文章主要介绍了asp.net中CSharpThinking扩展方法,实例讲述了扩展方法的特征及应用,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • C#基于Extension Method(扩展方法)获得文件大小的方法

    这篇文章主要介绍了C#基于Extension Method(扩展方法)获得文件大小的方法,实例分析了C#扩展方法的定义与文件操作的相关技巧,需要的朋友可以参考下...2020-06-25
  • C#扩展方法实例分析

    这篇文章主要介绍了C#扩展方法,结合实例形式分析了C#扩展方法的功能、使用方法及相关注意事项,需要的朋友可以参考下...2020-06-25
  • C# 扩展方法小结

    这篇文章主要介绍了C#的扩展方法的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-11-03
  • 详解C#扩展方法原理及其使用

    这篇文章主要介绍了C#扩展方法原理及其使用的的相关资料,文中代码非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-11-03
  • 解析C#的扩展方法

    在本文中,主要对扩展方法进行了一些规则说明、声明方式,使用方式,以及对扩展方法的意义和扩展方法的原理进行了简单的解答。并在本文的最后给了一个枚举的扩展方法代码。...2020-06-25
  • .NET实用扩展方法详解

    这篇文章主要为大家详细介绍了.NET实用扩展方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22