繁体   English   中英

泛型扩展方法

[英]Extension methods with generics

我一直在看这个问题,我很好奇为什么不编译。

有了这段代码,谁能解释为什么对IBase.Test()的调用无法解析为正确的扩展方法?

public interface IBase { }

public interface IChildA : IBase { }

public interface IChildB : IBase { }

public static class BaseExtensions
{
    public static IBase Test(this IBase self) { return self; }
    public static T Test<T>(this T self) where T : IChildB { return self; }
}

public static class TestClass
{
    public static void Test()
    {
        IChildA a = null; //Yeh i know its null but just testing for compile here..
        IBase firstTry = a.Test();  //Cannot resolve to BaseExtensions.Test(this IBase obj)
        IBase secondTry = ((IBase)a).Test();  //Resolves to BaseExtensions.Test(this IBase obj)

        IChildB b = null;
        IChildB touchedB = b.Test();
    }
}

我得到的错误是

Error 166 The type 'IChildA' cannot be used as type parameter 'T' in the generic type or method 'BaseExtensions.Test<T>(T)'. There is no implicit reference conversion from 'IChildA' to 'IChildB'.

我有一种感觉,因为它对于实现IChildB任何事物都是IChildB ,并且不知道要使用哪种扩展方法,但是错误消息不会IBase firstTry = a.Test();它的这一面,并且如果您删除IBase firstTry = a.Test(); 行,然后编译就可以了。

好的,问题是,在重载解析过程中,编译器会找到所有适用的候选方法, 而不会检查方法中指定的通用约束,选择最具体的约束, 然后检查通用约束。

在这种情况下,泛型方法比非泛型方法更具体(就像在类型参数替换之后一样,它实际上是带有IChildA参数而不是IBase参数的方法)-但是,它使约束失效。

我有一篇博客文章更详细地解释了这一点,另一篇文章以一种可怕的方式使用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM