C# 强制转换协变泛型接口类型时出现错误CS1503

C# 强制转换协变泛型接口类型时出现错误CS1503,c#,generics,covariance,C#,Generics,Covariance,使用C#9,我在尝试将实现某个接口的泛型类型转换为Func中的同一接口时遇到了CS1503错误,其中返回类型是协变的 示例代码: public interface ITest { ... } public class Test { private static readonly Dictionary<Type, Func<string, ITest>> constructors = new(); public static void Regis

使用C#9,我在尝试将实现某个接口的泛型类型转换为
Func
中的同一接口时遇到了CS1503错误,其中返回类型是协变的

示例代码:

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);
    }
}
公共接口测试
{
...
}
公开课考试
{
私有静态只读字典构造函数=new();
公共静态无效寄存器(Func构造函数),其中T:ITest
{
构造函数。添加(类型(T),构造函数);
}
}
错误出现在
Add
方法中:
参数1无法从Func转换为Func

奇怪的是,如果该接口是一个类,那么cast就可以正常工作。

是的,这是泛型协方差的预期行为,它与
Func
返回值的表示有关

当通过类约束
T
时,运行时知道委托返回的值将始终是引用-因此它只需要为引用分配足够的空间,而不管实际的func类型是什么

T
通过接口受到约束,但没有附加的“类”约束时,可以传入一个委托,该委托返回值类型值,而不是引用。这打破了协方差假设的所有东西

但是,您仍然可以使用接口—只要您也使用
约束约束
T
。像这样更改方法签名,它将编译:

公共静态无效寄存器(Func构造函数),其中T:class,ITest

有关表示(和标识)的更多信息,请参见和his。

是的,这是泛型协方差的预期行为,与来自
函数的返回值表示有关

当通过类约束
T
时,运行时知道委托返回的值将始终是引用-因此它只需要为引用分配足够的空间,而不管实际的func类型是什么

T
通过接口受到约束,但没有附加的“类”约束时,可以传入一个委托,该委托返回值类型值,而不是引用。这打破了协方差假设的所有东西

但是,您仍然可以使用接口—只要您也使用
约束约束
T
。像这样更改方法签名,它将编译:

公共静态无效寄存器(Func构造函数),其中T:class,ITest
有关表示(和身份)的更多信息,请参见和his