C# 方法解析,long 与 int

发布于 2024-11-09 08:49:41 字数 198 浏览 0 评论 0 原文

class foo
{
  public void bar(int i) { ... };
  public void bar(long i) { ... };
}


foo.bar(10);

我希望这段代码会给我一些错误,或者至少是一个警告,但事实并非如此......

调用了哪个版本的 bar() ,为什么?

class foo
{
  public void bar(int i) { ... };
  public void bar(long i) { ... };
}


foo.bar(10);

I would expect this code to give me some error, or at least an warning, but not so...

What version of bar() is called, and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无法言说的痛 2024-11-16 08:49:41

正在调用 int 版本的 bar,因为 10 是 int 文字,编译器将查找与输入变量最匹配的方法。要调用长版本,您需要指定一个长文本,如下所示: foo.bar(10L);

这是 Eric Lippert 发表的关于更复杂版本的方法重载的文章。我会尝试解释一下,但他做得更好,我也能做到:http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambigously-overloads-part-one.aspx

来自 C# 4.0 规范的

方法重载允许多个
同一类中的方法具有
相同的名称,只要它们具有唯一性
签名。当编译一个
调用重载方法,
编译器使用重载决策
来确定具体方法
调用。过载解析发现
最匹配的一种方法
参数或报告错误,如果没有
可以找到单个最佳匹配。这
以下示例显示了过载
决议生效。评论为
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)
      } 
}

如示例所示,特定的
方法始终可以通过以下方式选择
显式地将参数转换为
确切的参数类型和/或
显式提供类型参数。

The int version of bar is being called, because 10 is an int literal and the compiler will look for the method which closest matches the input variable(s). To call the long version, you'll need to specify a long literal like so: foo.bar(10L);

Here is a post by Eric Lippert on much more complicated versions of method overloading. I'd try and explain it, but he does a much better job and I ever could: http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx

from the C# 4.0 Specification:

Method overloading permits multiple
methods in the same class to have the
same name as long as they have unique
signatures. When compiling an
invocation of an overloaded method,
the compiler uses overload resolution
to determine the specific method to
invoke. Overload resolution finds the
one method that best matches the
arguments or reports an error if no
single best match can be found. The
following example shows overload
resolution in effect. The comment for
each invocation in the Main method
shows which method is actually
invoked.

 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)
      } 
}

As shown by the example, a particular
method can always be selected by
explicitly casting the arguments to
the exact parameter types and/or
explicitly supplying type arguments.

幸福%小乖 2024-11-16 08:49:41

正如凯文所说,有一个超载解决流程。该过程的基本概要是:

  • 识别所有可访问的候选方法,可能使用泛型方法的类型推断
  • 过滤掉不适用的方法;也就是说,这些方法无法工作,因为参数不会隐式转换为参数类型。
  • 一旦我们有了一组适用的候选者,就对它们运行更多的过滤器,以确定唯一的最佳候选者。

过滤器相当复杂。例如,最初在派生程度较高的类型中声明的方法总是比最初在派生程度较低的类型中声明的方法更好。参数类型与参数类型完全匹配的方法比不完全匹配的方法更好。等等。具体规则请参阅规范。

在您的特定示例中,“更好”算法很简单。 int 到 int 的精确匹配比 int 到 long 的不精确匹配要好。

As Kevin says, there's an overload resolution process in place. The basic sketch of the process is:

  • Identify all the accessible candidate methods, possibly using type inference on generic methods
  • Filter out the inapplicable methods; that is, the methods that cannot work because the arguments don't convert implicitly to the parameter types.
  • Once we have a set of applicable candidates, run more filters on them to determine the unique best one.

The filters are pretty complicated. For example, a method originally declared in a more derived type is always better than a method originally declared in a less derived type. A method where the argument types exactly match the parameter types is better than one where there are inexact matches. And so on. See the specification for the exact rules.

In your particular example the "betterness" algorithm is straightforward. The exact match of int to int is better than the inexact match of int to long.

白馒头 2024-11-16 08:49:41

我想说,如果超出限制,

-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);

Long 如果超出限制,将获得控制值 2147483648

I would say if you exceed below limit

-2,147,483,648 to 2,147,483,647

control will go to long

Range for long

–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

Max value for int

foo.bar(-2147483648);

or

foo.bar(2147483648);

Long will get control if we exceed the value by 2147483648

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文