为什么下面的代码不能编译?

本文关键字:不能 编译 代码 为什么 | 更新日期: 2023-09-27 18:05:03

我不明白为什么下面的代码不能编译:

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"。但是没有泛型也能很好地工作。

为什么下面的代码不能编译?

编译器无法推断类型。显式地指定它们:

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

V可以被推断,但T不能,因此对Foo的调用一定失败。

为什么T不能被推断?

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

我想你正在寻找这个作为你的扩展方法:

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

由于V始终是一个ITestCondition,因此确实没有理由使它更泛型。

当我考虑使用泛型参数时,我使用的一个快速的经验法则是"它是什么类型重要吗"。在这种情况下,特定类型J并不重要,重要的是父类型。所以不要使用泛型,只使用父类型。