c#实现自定义扩展方法

145 阅读2分钟

本文已参与「新人创作礼亅活动,一起开启掘金创作之路。

扩展方法

扩展方法其行为类似于某种类型(类、接口、结构体、原始值或枚举)的实例方法,目的为了增加原本类型不支持或需要多步操作的功能,所以扩展类命名一般为xxxExtensions。

例如下面代码

public static class StringExtension
{
    public static int WordCount(this String str)
    {
        return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}
class Program
{
    static void Main(string[] args)
    {
        string s = "The quick brown fox jumped over the lazy dog.";

        int i = s.WordCount();
        System.Console.WriteLine("Word count of s is {0}", i);
    }
}

StringExtension就是针对string类扩展了WordCount(this String str)方法,this 为此方法的关键字,指明此扩展为String类型,区分了扩展方法和一般的静态方法。

扩展类对扩展类型有几点说明: 1.这个类必须对外部可见,不能是Protected、private、internal等。 2.将扩展方法实现为静态方法,并且可见性至少与所在类可见性相同。 3.扩展方法的第一个参数为指定方法所操作的类型,参数前面必须加上this修饰符。 4.调用代码时,可添加using指定包含扩展方法类的命名空间。 5.调用方法跟调用类型的实例方法一样。

调用时不需要传入类型参数,可从arg1参数开始 Tset(this String str, int arg1) 对应调用方法 s.Test(1);

这个扩展还可以用在哪里呢?例如下面代码

public static bool IsNullOrEmpty(this ICollection i)
{
    return i == null || i.Count == 0;
}

这样就可以方便的判断那些继承了ICollection接口的数据结构,Array、List、Dictionary等,都可以直接使用这个方法。

总结

扩展方法可以写入最初没有提供该方法的类中,使得在多人开发的项目中可以保持一致实现方法,一般在工作中一些常用方法都会集中写到一个静态的工具类中,但是当工具类里的函数多了之后,查找起来并不容易,而且里面的函数跟某个类并没有强相关性。 这时候c#的这个扩展特性优势就体现出来了,像Unity中UI的显示隐藏其中一种优化方式就是,隐藏不是真的把gameobject隐藏,因为在频繁操作大量UI显示隐藏会有性能损耗,但是可以通过把scale隐藏时改成0。不过我们如果在每个需要隐藏UI的业务逻辑都写成改scale,容易遗忘而且不直观,可以这时候通过扩展出

public static void SetActiveEx(this Transform t, bool active)
{
    t.Scale = active ? Vector3.one : Vector3.zero;
}

还可以把方法添加到实现一个接口的任何类中,例如修改成(this IList i),这样每个继承了IList 接口的类都可以使用这个扩展方法。