转换协变泛型接口类型时出现错误 CS1503

Error CS1503 when casting covariant generic interface types

使用 C# 9,我在尝试从实现特定接口的泛型类型转换为 Func 中的相同接口时遇到了 CS1503 错误,其中 return 类型是协变的。

示例代码:

public interface ITest
{
    ...
}

public class Test
{
    private static readonly Dictionary<Type, Func<string, ITest>> constructors = new();

    public static void Register<T>(Func<string, T> constructor) where T : ITest
    {
        constructors.Add(typeof(T), constructor);
    }
}

错误在 Add 方法中:Argument 1 cannot convert from Func<string, T> to Func<string, ITest>。 奇怪的是,如果该界面是 class,则转换工作正常。

是的,这是泛型协变的预期行为,它与 Func.

中 return 值的表示有关

T 通过 class 约束时,运行时知道委托 return 的值将始终是一个引用 - 所以它只需要分配足够的 space 作为参考,不管它是什么实际 func 类型。

T 通过接口进行约束,但没有额外的“class”约束时,您可以传入一个委托,该委托 return 是值类型值,而不是引用.这打破了协方差假设的各种事物。

但是,您 可以 仍然使用接口 - 只要您还使用 class 约束来约束 T。像这样更改您的方法签名,它会编译:

public static void Register<T>(Func<string, T> constructor) where T : class, ITest

有关表示(和标识)的详细信息,请参阅 Eric Lippert's blog post on the topic and indeed his whole series on generic variance