为何存在重载方法时,C#优先选择int和double数据类型?
为什么CLR总是选择int和double的重载?
先看你给出的测试代码:
class Program { public static void Main() { var test = new Test(); test.Go(1); test.Go(100); test.Go(10000); test.Go(1.0); test.Go(100.0); test.Go(10000.0); test.Go(65535.0); test.Go(1000000000); test.Go(1000000000.0); } class Test { public void Go(int id) { Console.WriteLine(id + "int"); } public void Go(String id) { Console.WriteLine(id + "string"); } public void Go(short id) { Console.WriteLine(id + "short"); } public void Go(long id) { Console.WriteLine(id + "long"); } public void Go(double id) { Console.WriteLine(id + "double"); } public void Go(float id) { Console.WriteLine(id + "float"); } public void Go(decimal id) { Console.WriteLine(id + "decimal"); } } }
执行输出:
1int
100int
10000int
1double
100double
10000double
65535double
1000000000int
1000000000double
这其实是C#方法重载解析规则和字面量默认类型共同作用的结果——本质上是编译器在编译阶段就确定了要调用哪个重载,而非CLR运行时才决定,咱们具体拆解:
整数字面量的选择逻辑
- C#里,不带后缀的整数字面量,默认类型是
int,只要数值在int的取值范围(-2147483648 到 2147483647)内,编译器就会把它当成int处理。 - 你例子里的1、100、10000、1000000000都在这个范围内,所以直接匹配
Go(int)重载。要是你写一个超出范围的整数,比如2147483648(比int最大值大1),编译器会自动把它识别为long,这时候就会调用Go(long)重载了。 - 那为什么不匹配
short?虽然1、100这些值也符合short的范围,但编译器会优先选无需隐式转换的精确匹配——字面量本身就是int类型,所以直接用int重载,不会多此一举转成short。
浮点字面量的选择逻辑
- C#中,带小数点的字面量默认类型是
double,不管数值大小,只要是.形式的字面量,默认都是double类型。 - 所以你例子里的1.0、100.0这些,编译器都当成double处理,自然匹配
Go(double)重载。如果想让它匹配其他浮点类型,得加后缀:比如1.0f会被识别为float,1.0m会被识别为decimal,这时候就会调用对应的重载了。
总结来说:编译器选重载时,会优先找与实参默认类型完全匹配的方法,只有当没有完全匹配的选项时,才会考虑带隐式转换的候选方法。你的例子刚好有int和double的重载,所以它们就被优先选中了。
内容的提问来源于stack exchange,提问作者Cal
相关产品推荐
相关产品推荐

