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();
}
}
}
说明:以下测试是基于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();
}
}
}
相关文章推荐
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- Orcas Beta1 对多个同名扩展方法的处理逻辑
- 重构到扩展方法(4):轻松遍历WPF可视树与逻辑树
- 您的 PHP 似乎没有安装运行 WordPress 所必需的 MySQL 扩展”处理方法
- 第二百五十八节,Tornado框架-逻辑处理get()方法和post()方法,初识模板语言
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- MVC中处理表单提交的方式(使用html扩展方法+juqery插件)
- PHP扩展之图像处理3——ImageMagick使用及相关类和方法
- c#扩展方法奇思妙用基础篇一:中文处理
- 第三百零五节,Django框架,Views(视图函数),也就是逻辑处理函数里的各种方法与属性
- iPhone处理图片(UIImage扩展类) 自动适应frame大小方法
- 在Javascript中对String的一些方法扩展,实现常用的字符串处理。
- c++ 继承中的同名成员处理方法
- php结合mysql与mysqli扩展处理事务的方法
- jquery技巧总结-jQuery对象,集合,方法扩展,事件处理,特效,解决冲突
- 您的 PHP 似乎没有安装运行 WordPress 所必需的 MySQL 扩展”处理方法