C#方法parsing,long vs int
class foo { public void bar(int i) { ... }; public void bar(long i) { ... }; } foo.bar(10);
我希望这个代码给我一些错误,或至less一个警告,但不是这样的…
什么版本的bar()被调用,为什么?
bar的int版本被调用,因为10
是一个整型文本,编译器将查找最接近inputvariables的方法。 要调用长版本,你需要指定一个像这样的长文字: foo.bar(10L);
这里是Eric Lippert关于方法重载更复杂版本的post。 我会尽力解释,但他做得更好,我可以: http : //blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part- one.aspx
来自C#4.0规范:
方法重载允许同一个类中的多个方法具有相同的名称,只要它们具有唯一的签名即可。 编译重载方法的调用时,编译器使用重载parsing来确定要调用的特定方法。 如果找不到最佳匹配,则重载parsing会查找与参数最匹配的一个方法或报告错误。 以下示例显示重载parsing有效。 Main方法中每个调用的注释显示实际调用哪个方法。
class Test { static void F() { Console.WriteLine("F()"); } static void F(object x) { Console.WriteLine("F(object)"); } static void F(int x) { Console.WriteLine("F(int)"); } static void F(double x) { Console.WriteLine("F(double)"); } static void F<T>(T x) { Console.WriteLine("F<T>(T)"); } static void F(double x, double y) { Console.WriteLine("F(double,double)"); } static void Main() { F(); // Invokes F() F(1); // Invokes F(int) F(1.0); // Invokes F(double) F("abc"); // Invokes F(object) F((double)1); // Invokes F(double) F((object)1); // Invokes F(object) F<int>(1); // Invokes F<T>(T) F(1, 1); // Invokes F(double, double) } }
如示例所示,可以通过将参数明确地转换为确切的参数types和/或显式地提供types参数来始终select特定的方法。
正如Kevin所说,现在有一个重载解决的过程。 该过程的基本草图是:
- 确定所有可用的候选方法,可能使用generics方法的types推断
- 滤除不适用的方法; 也就是说,由于参数不会隐式转换为参数types,因此无法工作的方法。
- 一旦我们有一套适用的候选人,运行更多的filter,以确定唯一最好的。
filter非常复杂。 例如,最初在更多派生types中声明的方法始终优于最初在派生types较less的情况下声明的方法。 参数types与参数types完全匹配的方法优于不完全匹配的方法。 等等。 请参阅规范的确切规则。
在你的特定例子中,“更好”algorithm很简单。 int与int的精确匹配优于int与long的不精确匹配。
我会说如果你超过限制
-2,147,483,648 to 2,147,483,647
控制将会持续long
范围long
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
int的最大值
foo.bar(-2147483648);
要么
foo.bar(2147483648);
如果我们超过2147483648的值, Long
将得到控制