您的位置:首页 > 其它

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

2008-03-11 10:01 260 查看
扩展方法是一个双刃剑,你如果要用扩展方法,就一定得准备碰到别人也用扩展方法,并且万一出现你们都对同一个类进行扩展函数名,参数一样的扩展时候, 会出的各种问题.
 
说明:以下测试是基于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();
        }
    }
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐