博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

小天:除了使用分部类的方式,还有什么办法可以扩展已有的类没有?

老田:还有许多方法扩展类。如果有类的源代码,使用继承(后面章节讨论)就是给对象添加功能的好方法。但如果没有源代码则可以使用扩展方法,扩展方法使您能够向现有类型添加方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。换句话说,它允许改变一个类,但不需要类的源代码。

扩展方法是静态方法,是类的一部分,但实际上没有放在类的源代码中。还记得在本章开始的那个oopTool命名空间下的User类吧。现在我们再新的项目中去引用oopTool。但是接下来,我们需要做的是扩展User类,首先需要创建一个静态类,至于这个类的名称,推荐使用“要扩展类名 + Extension”的方式命名。在类中创建一个静态方法,代码如下:

using System;

using oopTool;

    public static class UserExtension

    {

        ///<summary>

        ///User扩展一个方法,根据用户名和年龄来判断用户是否存在

        ///</summary>

        ///<param name="user">this User user表示这个方法是User类的扩展方法</param>

        public static bool Exists(this User user,string name,int age)

        {

            if (user._name == name || user._age == age)

                return true;

            else

                return false;

        }

}

注意GetUser方法的参数。对于扩展方法,第一个参数是要扩展的类型,它放在this关键字的后面。这告诉编译器,这个方法是User类型的一部分。在这个例子中,User是要扩展的类型。在扩展方法中,可以访问所扩展类型的所有公共方法和属性。但是无法访问它们所扩展的类型中的私有变量。

另外,在代码中,可以使用实例方法语法调用该扩展方法。在主程序中,Exists方法看起来像是另一个方法。它没有显示第一个参数,也不能对它进行任何处理。要使用新方法,需要执行如下调用,这与其他方法相同:

//下面是展示如何使用到上面扩展类

        User u = new User();

        u._name = "thc";

        u._age = 29;

        bool tf = u.Exists("天轰穿", 30);   //调用User类的扩展方法Exists

        MessageBox.Show(tf.ToString());  //tf = false,为什么?

从使用的方法来看,即使扩展方法是静态的,也要使用标准的实例方法语法。注意这里使用u实例变量来调用Exists方法,而没有使用类型名。因为编译器生成的中间语言 (IL) 会将代码转换为对静态方法的调用。因此,并未真正违反封装原则。

注意:如果扩展方法与类中的某个方法同名,扩展方法就从来不会被调用。类中已有的实例方法优先。

此文章为天轰穿原创作品,转载请注明出处及作者。