为什么C#调用继承类重载方法时优先匹配double参数而非int参数?
C# 方法重载匹配问题原理说明
这个现象是C#的重载决议规则和隐式类型转换规则共同作用的结果,核心逻辑如下:
核心规则说明
- 重载候选查找优先级:编译器会优先在调用变量的编译时类型(你两个场景中变量
b的编译时类型都是Bull)中查找可匹配的方法,仅当当前类没有符合隐式转换要求的候选方法时,才会向上遍历基类查找。 - 隐式类型转换规则:
int类型可以无精度损失地隐式转换为double类型,但double类型无法隐式转换为int类型(存在精度丢失风险,必须显式强转)。
场景1运行逻辑
代码定义
class Animal { public void WriteMessage(int i) { Console.WriteLine("Message from Animal"); } } class Bull : Animal { public void WriteMessage(double p) { Console.WriteLine("Message from Bull"); } } static void Main(string[] args) { int i = 5; Bull b = new Bull(); b.WriteMessage(i); Console.ReadLine(); }
匹配过程
- 编译器先在
Bull类中查找候选方法,找到WriteMessage(double p)。 - 传入的参数是
int类型,符合int隐式转double的规则,匹配成功。 - 编译器直接调用
Bull类的方法,不会再去基类查找哪怕参数完全匹配的WriteMessage(int i)方法,因此输出Message from Bull。
场景2运行逻辑
代码定义
class Animal { public void WriteMessage(double i) { Console.WriteLine("Message from Animal"); } } class Bull : Animal { public void WriteMessage(int p) { Console.WriteLine("Message from Bull"); } } static void Main(string[] args) { double i = 5; Bull b = new Bull(); b.WriteMessage(i); Console.ReadLine(); }
匹配过程
- 编译器先在
Bull类中查找候选方法,找到WriteMessage(int p)。 - 传入的参数是
double类型,无法隐式转换为int,当前类没有符合要求的候选。 - 编译器向上查找基类
Animal,找到参数完全匹配的WriteMessage(double i),匹配成功,因此输出Message from Animal。
补充说明
你观察到的两次都执行double参数方法只是巧合,本质是上述规则的运行结果。如果在场景2中你将参数显式强转为int:b.WriteMessage((int)i);,就会匹配到Bull类的int参数方法,输出Message from Bull。
内容的提问来源于stack exchange,提问作者Mateusz Janota
相关产品推荐
相关产品推荐

