Orcas Beta1 对多个同名扩展方法的处理逻辑

扩展方法是一个双刃剑,你如果要用扩展方法,就一定得准备碰到别人也用扩展方法,并且万一出现你们都对同一个类进行扩展函数名,参数一样的扩展时候, 会出的各种问题.

 

说明:以下测试是基于Orcas Beta1环境的测试,VS2008 正式版发布后,也许会发生变化。

 

如果你对扩展方法不是很熟悉,建议先看我之前的两篇博客:

C#3.0 中的扩展方法 (Extension Methods)

C#3.0 中使用扩展方法来扩展接口

 

如果我们项目中,在不经意期间,出现了重名的扩展方法,这时候编译器会如何处理呢?这就是本文要探讨的问题。

 

先说结论:编译器按照下述三个优先级顺序去寻找到底哪个方法被调用到:

假设,我们是在A 命名空间下,调用 类 B 的 C 方法。 类的 C 方法可能是在 D 命名空间下使用扩展方法扩展实现的。

 

1、类 B 中是否真实存在 C 方法(非扩展方法),如果存在,则调用之,存在时,不考虑是否有扩展,直接进行调用。(这种情况请看我之前的博客:C#3.0 中的扩展方法 (Extension Methods)

2、命名空间 A ,是否存在对C方法的扩展,如果存在,则调用这种情况下的扩展;看示例代码二

3、调用代码中,除了 命名空间 A,还引用了其他命名空间 D和 F。A命名空间没有对C方法进行扩展,则调用D命名空间下的扩展。

 

特殊情况:

如果 F 和 D 命名空间都对 C 方法进行了扩展,则编译器报错误;看下面的示例代码一

如果 D 和 A命名空间都对 C 方法进行了扩展,则调用 A命名空间下的扩展,编译器不会报错;看示例代码二

 

示例代码一:

以下代码会编译时报错:

The call is ambiguous between the following methods or properties: 'ConsoleApplication1.MyClass01.DO(int)' and 'ConsoleApplication2.MyClass02.DO(int)

表明     using ConsoleApplication2;     using ConsoleApplication1;  导致 ConsoleApplication2 和 ConsoleApplication1  命名空间同级,同级搜索出现重名,报错。

namespace ConsoleApplication2
{
    using System;
    static class MyClass02
    {
        internal static void DO(this int i)
        {
            Console.WriteLine(string.Format("ConsoleApplication2.MyClass02.DO {0}", i));
        }
    }
}

namespace ConsoleApplication1
{
    using System;
    static class MyClass01
    {
        public static void DO(this int i)
        {
            Console.WriteLine(string.Format("HongJunGuo.MyClass01.DO {0}", i));
        }
    }
}

namespace HongJunGuo.Test
{
    using System;
    using ConsoleApplication2;
    using ConsoleApplication1;

    class Program
    {
        static void Main(string[] args)
        {
            int w = 9;
            w.DO();
            Console.ReadLine();
        }
    }
}

 

示例代码二

以下代码返回的信息为 HongJunGuo.MyClass01.DO 9, 标明优先找 本命名空间下的扩展方法。

namespace ConsoleApplication2
{
    using System;
    static class MyClass02
    {
        internal static void DO(this int i)
        {
            Console.WriteLine(string.Format("ConsoleApplication2.MyClass02.DO {0}", i));
        }
    }
}

namespace HongJunGuo.Test
{
    using System;
    using ConsoleApplication2;

    static class MyClass01
    {
        public static void DO(this int i)
        {
            Console.WriteLine(string.Format("HongJunGuo.MyClass01.DO {0}", i));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int w = 9;
            w.DO();
            Console.ReadLine();
        }
    }
}

 

特殊情况:如果出现下面的代码:

编译器并不会报错,返回的信息是 ConsoleApplication2.MyClass02.DO , ConsoleApplication2.MyClass02.DO MyObject

原因: 上级命名空间在处理逻辑上跟其他命名空间处理逻辑是一样的.


namespace ConsoleApplication2
{
    using System;
    using HongJunGuo.Test;
    static class MyClass02
    {
        public static void DO(this int i)
        {
            Console.WriteLine(string.Format("ConsoleApplication2.MyClass02.DO {0}", i));
        }

        public static void DO(this MyObject obj)
        {
            Console.WriteLine("ConsoleApplication2.MyClass02.DO MyObject");
        }
    }
}

namespace HongJunGuo
{
    using System;
    using HongJunGuo.Test;
    static class MyClass01
    {
        public static void DO(this int i)
        {
            Console.WriteLine(string.Format("HongJunGuo.MyClass01.DO {0}", i));
        }

        public static void DO(this MyObject obj)
        {
            Console.WriteLine("HongJunGuo.MyClass01.DO MyObject");
        }
    }

}

namespace HongJunGuo.Test
{
    using System;
    using ConsoleApplication2;

    public class MyObject
    {
        public MyObject()
        {

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int w = 9;
            w.DO();
            MyObject obj = new MyObject();
            obj.DO();

            Console.ReadLine();
        }
    }
}

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1649494


你可能感兴趣的:(cas)