Console.WriteLine(Enum.Value)は、C#とVB.Netで異なる出力を提供します

Nikhil Agrawal

私は基本的にC#の人ですが、最近はVB.Netコードを書いています。

今日、私は.Netの非常に異なる動作に遭遇しました

C#コード

enum Color
{
   Red,
   Green,
   Blue
}

class Demo
{
    public static void Main()
    {
        System.Console.WriteLine(Color.Red);
    }
}

このプリント Red

ただし、このコードをVB.Netで記述すると、が出力され0ます。

VB.Netコード

Module Module1

    Sub Main()
        System.Console.WriteLine(Color.Red)
    End Sub

End Module

Enum Color
    Red
    Green
    Blue
End Enum

なぜそんなに違うの?

Lucas Trzesniewski

C#とVB.NETには、異なるメソッドオーバーロード解決ルールがあります。

C#Console.WriteLine(Object)はを選択し、VB.NETはを選択しConsole.WriteLine(Int32)ます。なぜそうなるのか見てみましょう。

VB.NETルール

  1. アクセシビリティ。呼び出し元のコードがそれを呼び出さないようにするアクセスレベルでの過負荷を排除します。

  2. パラメータの数。呼び出しで提供されるものとは異なる数のパラメーターを定義する過負荷を排除します。

  3. パラメータデータ型。コンパイラは、拡張メソッドよりもインスタンスメソッドを優先します。プロシージャ呼び出しに一致するために拡張変換のみを必要とするインスタンスメソッドが見つかった場合、すべての拡張メソッドが削除され、コンパイラはインスタンスメソッド候補のみを続行します。そのようなインスタンスメソッドが見つからない場合は、インスタンスメソッドと拡張メソッドの両方で続行されます。
    このステップでは、呼び出し元の引数のデータ型をオーバーロードで定義されたパラメータータイプに変換できないオーバーロードを排除します。

  4. コンバージョンの絞り込み。これにより、呼び出し元の引数タイプから定義済みのパラメータータイプへの変換を絞り込む必要があるオーバーロードが排除されます。これは、型チェックスイッチ(Option Strict Statement)がオンかオフかに関係なく当てはまります。

  5. 最小の拡大。コンパイラーは、残りのオーバーロードをペアで考慮します。ペアごとに、定義されたパラメーターのデータ型を比較します。一方のオーバーロードの型がすべてもう一方の対応する型に広がる場合、コンパイラーは後者を排除します。つまり、最小限の拡張を必要とする過負荷を保持します。

  6. 単一の候補者。オーバーロードが1つだけ残るまで、ペアでオーバーロードを検討し続け、そのオーバーロードへの呼び出しを解決します。コンパイラがオーバーロードを単一の候補に減らすことができない場合、エラーが生成されます。

には多くのオーバーロードがありWriteLine、そのうちのいくつかはステップ3で破棄されます。基本的に次の可能性が残されています:Objectおよび数値タイプ。

5番目のポイントはここで興味深いです:最小の拡大では、拡大ルールは何と言っていますか?

列挙型(Enum)は、基になる整数型と、基になる型が広がる型に広がります。

どんなタイプも Object

したがって、Color列挙型は最初にInt32(その基になるデータ型)に広がります-これはConsole.WriteLine(Int32)。と100%一致します。からに移行するには、さらに別の拡大変換が必要になりますが、上記のルールでは、最小限の拡大を必要とする過負荷保持するように指示されInt32Objectいます


C#について(§7.5.3.2のC#5仕様から):

引数式のセットで引数リストのAを考える{ E1, E2, ..., EN }と2人の該当する関数メンバーMPMQパラメータの型を持つ{ P1, P2, ..., PN }{ Q1, Q2, ..., QN }MPより優れた機能のメンバーであると定義されているMQ場合

  • 各引数のために、からの暗黙的な変換EXにはQX、より良いから暗黙の型変換以下ではないEXPXし、
  • 少なくとも1つの引数については、からEXPXの変換はからEXの変換よりも優れていQXます。

では、どのように定義するのがよいでしょうか(§7.5.3.4)?

変換指定されたC1型から変換するSタイプにT1、変換C2タイプから変換するSタイプにはT2C1より良好変換であるC2:以下のうちの少なくとも一方が成立する場合

  • 恒等変換が存在しているからST1ではなく、からST2
  • T1T2(§7.5.3.5)よりも優れたコンバージョンターゲットです

§7.5.3.5で見てみましょう:

二つの異なる種類を考えるT1T2T1より優れた変換対象でT2、以下のうちの少なくとも1つが保持している場合:

  • 以下からの暗黙的な変換T1にはT2存在している、との暗黙の変換T2にはT1存在しません
  • T1T2符号付き整数型であり、符号なし整数型です。

したがって、からまたはのColorいずれかに変換していますこれらのルールに従ってどちらが良いですか?ObjectInt32

  • そこの暗黙的な変換Colorには、Object
  • からObjectの暗黙の変換はありませんColor(明らかに)
  • からColorの暗黙の変換はありませんInt32(これらはC#で明示的です)
  • からInt32の暗黙の変換はありませんColor(を除く0

仕様§6.1:

次の変換は、暗黙的な変換として分類されます。

  • ID変換
  • 暗黙の数値変換
  • 暗黙的な列挙変換。
  • 暗黙のnull許容変換
  • ヌルリテラル変換
  • 暗黙の参照変換
  • ボクシングのコンバージョン
  • 暗黙の動的変換
  • 暗黙の定数式変換
  • ユーザー定義の暗黙的な変換
  • 匿名関数の変換
  • メソッドグループの変換

暗黙の数値変換では列挙型については言及されておらず、暗黙の列挙変換ではその逆が処理されます。

暗黙的な列挙型変換により、decimal-integer-literal0を任意の列挙型および基になる型が列挙であるnull許容型に変換できます。後者の場合、変換は、基になる列挙型に変換し、結果をラップすることによって評価されます(§4.1.10)。

列挙型はボクシング変換によって処理されます(§6.1.7):

ボクシング変換では、値型を暗黙的に参照型に変換できますボクシングの変換は、任意の存在する非null許容値型objectdynamicに、System.ValueType及び任意に界面型によって実装非null許容値型さらに、列挙型に変換できますSystem.Enum

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

C#Console.WriteLineは、Char型を整数として出力します

分類Dev

C#Console.WriteLine奇妙な

分類Dev

C ++ / CLI:Console :: WriteLine()またはcout?

分類Dev

C#でConsole.WriteLineの代わりにWriteLineのみを書き込むことは可能ですか?

分類Dev

document.writeとconsole.logがgetElementByIdに対して異なる出力を提供するのはなぜですか?

分類Dev

Console.WriteLine()とConsole.WriteLine(string.Empty)

分類Dev

Console.WriteLineとPrint

分類Dev

Console.Writelineが大きな出力をカットオフC#

分類Dev

Debug.WriteLine()とConsole.WriteLine()は、カルチャの処理が異なります。どうして?

分類Dev

console.writelineを使用してフォーマットされた出力を異なる色で表示する方法

分類Dev

要素$(this)はconsole.logに異なる形式を出力します

分類Dev

Array.push()とconsole.log()は異なる変数を提供します

分類Dev

F#:printfとConsole.WriteLine

分類Dev

Xamarinの場合、Console.Writelineを使用し、代わりにDebug.Writelineを使用する必要がある場合の出力はどこにありますか?

分類Dev

Console.WriteLineはASP.NETのどこにありますか?

分類Dev

c#で単一のConsole.WriteLineにfloat.ParseまたはTryParseを実行する方法

分類Dev

Visual Studio for Macでconsole.writelineが機能しないのはなぜですか?

分類Dev

Console.WriteLineがVisualStudio Codeで機能しないのはなぜですか?

分類Dev

Console.Writeline、Console.WriteがVisual Studio Expressで機能しないのはなぜですか?

分類Dev

MicrosoftがメソッドConsole.Write()およびConsole.WriteLine()をオーバーロードする理由 C#

分類Dev

カラーテキストを含むc#Console.WriteLine()が出力をまとめています

分類Dev

1つのConsole.WriteLine()ステートメントで複数の変数の値を出力する方法は?

分類Dev

Console.WriteLineを使用して変数を出力する方法

分類Dev

フォーマット文字列を使用すると、Console.WriteLineがフォーマット文字列とタイプ名なしでテキストを出力するのはなぜですか?

分類Dev

「toLocaleString」は、異なるブラウザで異なる出力を提供します

分類Dev

Console.Readline()の後のC#コンソールConsole.WriteLine()?

分類Dev

Console.WriteLineとデバッガーがWindows / VSCで機能しませんか?

分類Dev

「Write-Host」、「Write-Output」、または「[console] :: WriteLine」の違いは何ですか?

分類Dev

文字列を使用したConsole.writeline

Related 関連記事

  1. 1

    C#Console.WriteLineは、Char型を整数として出力します

  2. 2

    C#Console.WriteLine奇妙な

  3. 3

    C ++ / CLI:Console :: WriteLine()またはcout?

  4. 4

    C#でConsole.WriteLineの代わりにWriteLineのみを書き込むことは可能ですか?

  5. 5

    document.writeとconsole.logがgetElementByIdに対して異なる出力を提供するのはなぜですか?

  6. 6

    Console.WriteLine()とConsole.WriteLine(string.Empty)

  7. 7

    Console.WriteLineとPrint

  8. 8

    Console.Writelineが大きな出力をカットオフC#

  9. 9

    Debug.WriteLine()とConsole.WriteLine()は、カルチャの処理が異なります。どうして?

  10. 10

    console.writelineを使用してフォーマットされた出力を異なる色で表示する方法

  11. 11

    要素$(this)はconsole.logに異なる形式を出力します

  12. 12

    Array.push()とconsole.log()は異なる変数を提供します

  13. 13

    F#:printfとConsole.WriteLine

  14. 14

    Xamarinの場合、Console.Writelineを使用し、代わりにDebug.Writelineを使用する必要がある場合の出力はどこにありますか?

  15. 15

    Console.WriteLineはASP.NETのどこにありますか?

  16. 16

    c#で単一のConsole.WriteLineにfloat.ParseまたはTryParseを実行する方法

  17. 17

    Visual Studio for Macでconsole.writelineが機能しないのはなぜですか?

  18. 18

    Console.WriteLineがVisualStudio Codeで機能しないのはなぜですか?

  19. 19

    Console.Writeline、Console.WriteがVisual Studio Expressで機能しないのはなぜですか?

  20. 20

    MicrosoftがメソッドConsole.Write()およびConsole.WriteLine()をオーバーロードする理由 C#

  21. 21

    カラーテキストを含むc#Console.WriteLine()が出力をまとめています

  22. 22

    1つのConsole.WriteLine()ステートメントで複数の変数の値を出力する方法は?

  23. 23

    Console.WriteLineを使用して変数を出力する方法

  24. 24

    フォーマット文字列を使用すると、Console.WriteLineがフォーマット文字列とタイプ名なしでテキストを出力するのはなぜですか?

  25. 25

    「toLocaleString」は、異なるブラウザで異なる出力を提供します

  26. 26

    Console.Readline()の後のC#コンソールConsole.WriteLine()?

  27. 27

    Console.WriteLineとデバッガーがWindows / VSCで機能しませんか?

  28. 28

    「Write-Host」、「Write-Output」、または「[console] :: WriteLine」の違いは何ですか?

  29. 29

    文字列を使用したConsole.writeline

ホットタグ

アーカイブ