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

为何以下代码调用Func(object)而非Func(int)?请验证原因是否正确

问题解答:为何装箱int会调用Func(object),以及原因分析

首先直接给结论:你提出的“所有类型都派生自System.Object”这个说法不是导致这个行为的核心原因,真正的关键是C#的重载决议(Overload Resolution)规则。

我们一步步拆解这个问题:

1. 编译时类型 vs 运行时类型

你代码里的变量object i = 10;,它的编译时类型是object——虽然运行时它是一个装箱的int,但编译器在做重载匹配的时候,只会基于变量的编译时类型来查找合适的方法,不会提前考虑它的运行时实际类型。

2. 重载匹配的优先级逻辑

当你调用d.Func(i)时,编译器会按以下顺序查找匹配的方法:

  • 首先在Derived类的直接成员里找:Derived有两个Func重载,一个是重写基类的Func(int),另一个是自己定义的Func(object)。
  • 对于编译时类型为object的参数i,Func(object o)是完全匹配的重载,不需要任何类型转换就能调用,优先级最高。
  • 而要匹配Func(int x),需要把object类型的i拆箱转换成int——这是一个需要显式操作的转换(编译器不会自动帮你做这个拆箱来匹配另一个重载),所以这个重载的优先级远低于完全匹配的Func(object)。

这就是为什么最终调用的是Derived.Func(object)。

3. 验证你的假设是否正确

如果“所有类型派生自object”是核心原因,那当Derived没有定义Func(object)时,应该不会调用Func(int),但实际情况并非如此:

// 修改Derived类,去掉Func(object)重载
public class Derived : Base {
    public override void Func(int x) {
        Console.WriteLine("Derived.Func(int)");
    }
}

这时候调用d.Func(i),编译器会向上查找基类Base的Func(int),并尝试把object拆箱成int(因为这是唯一可行的匹配),最终会输出Derived.Func(int)——这说明“所有类型派生自object”并不是决定因素,核心还是重载匹配的规则。

4. 如何让它调用Func(int)

如果你希望调用int版本的重载,只需要显式地把i拆箱成int:

d.Func((int)i);

这时候参数的编译时类型是int,编译器会匹配Derived.Func(int),输出Derived.Func(int)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:51:21