阿不

潜水

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  212 随笔 :: 0 文章 :: 3066 评论 :: 75 引用

公告

我们时常会为某一种具有相同的类(基类)或接口定义泛型的扩展方法,此时我们只需要在泛型扩展方法上加上泛型约束后,编译器在使用该类的派生类时就会自动筛选出可用的扩展方法。如下的定义:

public interface Interface1
{ }
public class Class1 : Interface1
{
}

此时我们为Interface1定义一个扩展方法如下:

namespace Extension1
{
    
    public static class Class1Extensions
    {
        public static T AsActual<T>(this T o)
            where T : Interface1
        {
            return o;
        }
    }
}

Image1

这很好,泛型的约束很好的表达了我们的意图。这个约束这时候能很好的避免这个扩展方法污染到其它类型的对象。接下来,当我们希望为再为其它的类型或接口定义相同的扩展方法时,有兴趣的事情就会发生,另外一个接口和实现:

public interface Interface2
{ }
public class Class2 : Interface2
{
}

接下来我们再为Interface2,在不同的名称空间定义相同名称的扩展方法,但约束不一样:

namespace Extension2
{
    
    public static class Class2Extensions
    {
        public static T AsActual<T>(this T o)
            where T : Interface2
        {
            return o;
        }
    }
}

这时,我们再引用Extension2这个名称空间,编译下面的代码:

Class1 obj = new Class1();
obj.AsActual();

此时就会编译失败,编译器告诉我们,它无法决定使用哪个版本的扩展方法。可问题是,我们分别对两个扩展方法进行了泛型约束了,当扩展方法名称不相同时,它们是不会互相污染的。出现这种奇怪的行为是编译器的bug,还是有什么理由可以来解释呢?扩展方法,虽然从使用上类似于类的成员方法调用,但是从IL级别来理解的话,它就是普通的静态函数调用。难道编译器无法做到自动去判断,相同名称而不同约束的泛型扩展方法?诡异

posted on 2010-09-18 23:08 阿不 阅读(...) 评论(...) 编辑 收藏