• <tfoot id='puUtl'></tfoot>
      <bdo id='puUtl'></bdo><ul id='puUtl'></ul>
      <legend id='puUtl'><style id='puUtl'><dir id='puUtl'><q id='puUtl'></q></dir></style></legend>

        <small id='puUtl'></small><noframes id='puUtl'>

        <i id='puUtl'><tr id='puUtl'><dt id='puUtl'><q id='puUtl'><span id='puUtl'><b id='puUtl'><form id='puUtl'><ins id='puUtl'></ins><ul id='puUtl'></ul><sub id='puUtl'></sub></form><legend id='puUtl'></legend><bdo id='puUtl'><pre id='puUtl'><center id='puUtl'></center></pre></bdo></b><th id='puUtl'></th></span></q></dt></tr></i><div id='puUtl'><tfoot id='puUtl'></tfoot><dl id='puUtl'><fieldset id='puUtl'></fieldset></dl></div>

        带有方法重载和枚举的奇怪(可能是错误的?)C# 编译器行为

        时间:2023-10-06

          <bdo id='C3SDO'></bdo><ul id='C3SDO'></ul>

          <small id='C3SDO'></small><noframes id='C3SDO'>

              <tbody id='C3SDO'></tbody>

              • <tfoot id='C3SDO'></tfoot>
                <i id='C3SDO'><tr id='C3SDO'><dt id='C3SDO'><q id='C3SDO'><span id='C3SDO'><b id='C3SDO'><form id='C3SDO'><ins id='C3SDO'></ins><ul id='C3SDO'></ul><sub id='C3SDO'></sub></form><legend id='C3SDO'></legend><bdo id='C3SDO'><pre id='C3SDO'><center id='C3SDO'></center></pre></bdo></b><th id='C3SDO'></th></span></q></dt></tr></i><div id='C3SDO'><tfoot id='C3SDO'></tfoot><dl id='C3SDO'><fieldset id='C3SDO'></fieldset></dl></div>
              • <legend id='C3SDO'><style id='C3SDO'><dir id='C3SDO'><q id='C3SDO'></q></dir></style></legend>
                  本文介绍了带有方法重载和枚举的奇怪(可能是错误的?)C# 编译器行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  今天我发现了一个非常奇怪的 C# 函数重载行为.当我有一个具有 2 个重载的方法,一个接受 Object 而另一个接受任何类型的 Enum 时,就会出现问题.当我将 0 作为参数传递时,将调用该方法的 Enum 版本.当我使用任何其他整数值时,将调用 Object 版本.我知道这可以通过使用显式强制转换轻松解决,但我想知道编译器为什么会这样.这是一个错误还是只是我不知道的一些奇怪的语言规则?

                  today I discovered a very strange behavior with C# function overloading. The problem occurs when I have a method with 2 overloads, one accepting Object and the other accepting Enum of any type. When I pass 0 as parameter, the Enum version of the method is called. When I use any other integer value, the Object version is called. I know this can be easilly fixed by using explicit casting, but I want to know why the compiler behaves that way. Is this a bug or just some strange language rule I don't know about?

                  下面的代码解释了问题(使用运行时 2.0.50727 检查)

                  The code below explains the problem (checked with runtime 2.0.50727)

                  感谢您对此的任何帮助,Grzegorz Kyc

                  Thanks for any help on this, Grzegorz Kyc

                  class Program
                  {
                      enum Bar
                      {
                          Value1,
                          Value2,
                          Value3
                      }
                  
                      static void Main(string[] args)
                      {
                          Foo(0);
                          Foo(1);
                          Console.ReadLine();
                      }
                  
                      static void Foo(object a)
                      {
                          Console.WriteLine("object");
                      }
                  
                      static void Foo(Bar a)
                      {
                          Console.WriteLine("enum");
                      }
                  }
                  

                  推荐答案

                  你可能不知道有一个从 0 的常量1 到任何枚举的隐式转换:

                  It may be that you're not aware that there's an implicit conversion from a constant1 of 0 to any enum:

                  Bar x = 0; // Implicit conversion
                  

                  现在,从 0 到 Bar 的转换比从 0 到 object 的转换更具体,这就是为什么 Foo(Bar) 使用了重载.

                  Now, the conversion from 0 to Bar is more specific than the conversion from 0 to object, which is why the Foo(Bar) overload is used.

                  一切都清楚了吗?

                  1 实际上,Microsoft C# 编译器中存在一个错误,它使它成为 any 零常量,而不仅仅是一个整数:

                  1 There's actually a bug in the Microsoft C# compiler which lets it be any zero constant, not just an integer:

                  const decimal DecimalZero = 0.0m;
                  
                  ...
                  Bar x = DecimalZero;
                  

                  这不太可能得到修复,因为它可能会破坏现有的工作代码.我相信 Eric Lippert 有两个 博客 帖子更详细.

                  It's unlikely that this will ever be fixed, as it could break existing working code. I believe Eric Lippert has a two blog posts which go into much more detail.

                  C# 规范第 6.1.3 节(C# 4 规范)对此有这样的说法:

                  The C# specification section 6.1.3 (C# 4 spec) has this to say about it:

                  隐式枚举转换允许 decimal-integer-literal 0转换为任何枚举类型和任何 nullable-type 其底层type 是一个枚举类型.在后者如果转换由转换为底层的枚举类型并包装结果(§4.1.10).

                  An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type and to any nullable-type whose underlying type is an enum-type. In the latter case the conversion is evaluated by converting to the underlying enum-type and wrapping the result (§4.1.10).

                  这实际上表明该错误不仅在于允许错误的类型,还在于允许转换任何常量 0 值,而不仅仅是文字值 0.

                  That actually suggests that the bug isn't just in allowing the wrong type, but allowing any constant 0 value to be converted rather than only the literal value 0.

                  它看起来像常数";部分是 在 C# 3 编译器中部分引入.以前是一些个常量值,现在看起来就是全部了.

                  It looks like the "constant" part was partially introduced in the C# 3 compiler. Previously it was some constant values, now it looks like it's all of them.

                  这篇关于带有方法重载和枚举的奇怪(可能是错误的?)C# 编译器行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:通过命令行编译c#代码时如何使用引用 下一篇:根据项目类型和视图选项切换 ListBox ItemTemplate

                  相关文章

                  <small id='dpuXO'></small><noframes id='dpuXO'>

                  1. <legend id='dpuXO'><style id='dpuXO'><dir id='dpuXO'><q id='dpuXO'></q></dir></style></legend><tfoot id='dpuXO'></tfoot>

                  2. <i id='dpuXO'><tr id='dpuXO'><dt id='dpuXO'><q id='dpuXO'><span id='dpuXO'><b id='dpuXO'><form id='dpuXO'><ins id='dpuXO'></ins><ul id='dpuXO'></ul><sub id='dpuXO'></sub></form><legend id='dpuXO'></legend><bdo id='dpuXO'><pre id='dpuXO'><center id='dpuXO'></center></pre></bdo></b><th id='dpuXO'></th></span></q></dt></tr></i><div id='dpuXO'><tfoot id='dpuXO'></tfoot><dl id='dpuXO'><fieldset id='dpuXO'></fieldset></dl></div>

                    • <bdo id='dpuXO'></bdo><ul id='dpuXO'></ul>