为什么以下代码无法编译?

时间:2013-03-21 15:47:57

标签: c# generics types compiler-errors

我无法理解为什么以下代码无法编译:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1 {
    public interface ITestCondition<T> {
    }

    public class TestConditionBase<T>: ITestCondition<T> {
    }

    public class TestCondition<T>: TestConditionBase<T> {
    }

    public static class TestConditionExtension {
        public static V Foo<V, T>(this V condition) where V: ITestCondition<T> {
            return condition;
        }
    }

    class Program {
        static void Main(string[] args) {
            new TestCondition<int>().Foo();
        }
    }
}

它说它找不到“foo”。但它没有通用类型就能完美运行。

3 个答案:

答案 0 :(得分:5)

编译器无法推断出类型。明确指定它们:

new TestCondition<int>().Foo<TestCondition<int>, int>();

答案 1 :(得分:4)

可以推断V但是T不能,因此对Foo的调用必须失败。

为什么不能推断?

执行方法类型推断时 C#永远不会从约束进行类型推断。通过检查参数与其对应的形式参数类型之间的关系来进行推理。只有在推断完成后,我们才会检查是否满足约束。

答案 2 :(得分:3)

我认为您正在寻找这种扩展方法:

public static class TestConditionExtension
{
    public static ITestCondition<T> Foo<T>(this ITestCondition<T> condition)
    {
        return condition;
    }
}

由于V始终是ITestCondition,因此没有理由让它更通用。

当我考虑使用泛型参数时,我使用的一个快速经验法则是“它的类型是否重要”。在这种情况下,特定类型J无关紧要,只是父类型。所以不要使用泛型,只需使用父类型。希望这是有道理的。