您的位置:首页 > 其它

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

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



说明:以下测试是基于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();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐