You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Func<TResult>的协变无法生效?——关于Func<int>无法赋值给Func<object>的技术问询

为什么Func<int>无法赋值给Func<object>?

这是个很典型的协变场景疑问,先给你澄清一个核心事实:在C# 4.0及以上版本中,标准库的Func<int>其实是可以隐式转换为Func<object>的——因为System.Func<out TResult>的TResult参数是用out关键字标记的协变类型参数,完全符合你提到的协变原则(返回值类型可以从派生类安全转为基类)。

那你遇到编译器报错的情况,大概率是下面两种原因之一:

  • 你使用的C#版本低于4.0
    协变和逆变特性是C# 4.0才引入的语言功能,如果你的项目目标框架是.NET Framework 3.5或更早版本,或者编译器语言版本设置为4.0以下,这种隐式转换就会被禁止。你可以检查项目属性里的语言版本设置,或者升级到支持C#4.0及以上的框架版本。

  • 你自定义了非协变的Func<T>委托
    如果你的代码里自己定义了一个名为Func<T>的委托,比如:

    delegate T Func<T>(); // 没有out修饰符
    

    这个自定义委托没有标记out,所以不支持协变。此时你需要要么改用系统内置的System.Func<T>,要么给自定义委托的类型参数加上out修饰符:

    delegate T Func<out T>(); // 现在支持协变了
    

举个验证的例子,在C#4.0+环境下,这段代码是完全合法的:

using System;

class Program
{
    static int FuncA() { return 0; }
    
    static void Main()
    {
        Func<int> a = FuncA;
        Func<object> b = a; // 编译通过,协变生效
        Console.WriteLine(b()); // 输出0
    }
}

总结一下:协变在Func<TResult>上是正常生效的,你遇到的问题大概率是环境版本或者自定义委托的配置问题。

内容的提问来源于stack exchange,提问作者Cool Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 22:32:39