1

好的,我被告知,由于逆变,编译器应该能够推断出 T=Circle 并因此允许编译。但是,使用编译器版本 4.0.30319.1 我收到以下错误:

错误 CS0311:类型“Testable.Shape”不能用作泛型类型或方法“Testable.Test.Foo(System.IComparable,T)”中的类型参数“T”。没有从“Testable.Shape”到“Testable.ICircle”的隐式引用转换。

但是,如果我在 Circle 类上实现 IComparable,则代码可以正常编译。这里可能有什么问题?

using System; 

namespace Testable 
{ 
    public class Test 
    { 
        public static void Main() 
        { 
            Foo(new Circle(), new Circle()); 
        } 

        public static void Foo<T>(IComparable<T> a, T b) where T : ICircle 
        { 
            a.CompareTo(b); 
        } 
    } 

    public interface ICircle 
    { 
    } 

    public class Shape : IComparable<Shape>
    { 
        public Int32 CompareTo(Shape other) 
        { 
            Console.WriteLine("Called CompareTo(Shape)"); 
            return 0; 
        } 
    } 

    public class Circle : Shape, ICircle 
    { 
    } 
}
4

1 回答 1

2

问题是Circleimplements IComparable<Shape>,所以编译器选择Shape了 T。但是,Shape没有 implements ICircle,所以你会看到你看到的错误。

不过,我想这引出了问题。为什么编译器Circle在看到ICircle约束后不修改它的猜测。答案是约束不用于帮助类型推断。他们只能在猜测完成后才能使猜测无效

于 2012-08-09T16:57:31.700 回答