2011-02-02 18 views
2

文字列ビルダを使用すると、enumが入力であるときにappendとappend行関数から期待される結果が得られますが、enumがボックス化されてappend行とappend関数異なる結果。StringBuilder AppendとAppendLineはEnumに対して異なる結果を返す

これの背後にあるものは誰でも教えてください。

コード出力:

Append Enum: 1 
Append Enum To String: One 
Append Line Enum: 1 
Append Line Enum To String: One 
Append Object: One 
Append Object To String: One 
Append Line Object: 1 
Append Line Object To String: One 

コード:

Public Enum eTest 
    One = 1 
    Two = 2 
End Enum 

Sub Main() 
    Dim sb As New System.Text.StringBuilder() 
    Dim x = eTest.One 
    sb.Append("Append Enum: ").Append(x).AppendLine() 
    sb.Append("Append Enum To String: ").Append(x.ToString()).AppendLine() 
    sb.Append("Append Line Enum: ").AppendLine(x) 
    sb.Append("Append Line Enum To String: ").AppendLine(x.ToString()) 

    Dim o As Object = x 
    sb.Append("Append Object: ").Append(o).AppendLine() 
    sb.Append("Append Object To String: ").Append(o.ToString()).AppendLine() 
    sb.Append("Append Line Object: ").AppendLine(o) 
    sb.Append("Append Line Object To String: ").AppendLine(o.ToString()) 

    Console.WriteLine(sb.ToString()) 


    '=============================== 
    Console.ReadKey() 
End Sub 
+0

Put Option Strictをファイルの先頭に設定すると、その違いを取り除くことができます。 –

答えて

6

このライン

sb.Append("Append Object: ").Append(o).AppendLine() 
o.ToString()StringBuilderのインスタンスに付加させると、その差分である

。もちろん、その呼び出しは列挙型のボックス化されたインスタンスに渡されます。このため、この呼び出しではOneが表示されます。

オーバーロードStringBuilder.Append(object)を呼び出しているため、渡されたオブジェクトのインスタンスでo.ToString()が呼び出されるだけです。これは、ドキュメントに明示的である:

Append方法は、valueの文字列表現を取得するObject.ToStringメソッドを呼び出します。 valuenullの場合、StringBuilderオブジェクトは変更されません。一方

、あなたはxは、列挙型のインスタンスである、xが暗黙のうちに過負荷StringBuilder.Append(int)を呼び出しますintのインスタンスに変換されます

sb.Append("Append Enum: ").Append(x).AppendLine() 

を呼び出します。

これはVB.NETに固有のことに注意してください。 StringBuilder.Appendのどちらのオーバーロードを呼び出すかを選択すると、C#は暗黙的にxintに変換しません。 StringBuilder.Append(object)が呼び出されます。

+0

私は私が大丈夫だと思う部分は、私にとって興味深いのは、それぞれ "One"と "1"を出力する.Append(o)と.AppendLine(o)の出力の違いです。ボックス化されたオブジェクトの両方の関数への呼び出しが同じ結果を返すことを期待します。 –

+2

これはVB.NETです。 'StringBuilder.AppendLine'のオーバーロードは2つしかありません。最初は 'AppendLine()'で、2番目は 'AppendLine(string)'です。最初はここでは適用できません。したがって、それが最初に適用されます。そこで、 'string'型のパラメータを受け取るメソッドに' object'として宣言された変数を渡しています。 VB.NETは 'Microsoft.VisualBasic.CompilerServices.Conversions.ToString(object)'を呼び出し、 'o'が' Int32'のインスタンスに変換可能であることを検出し、 'Int32.ToString'を呼び出します。 'Option Strict On'を追加してください。これは起こりません。それはC#でも起こりません。 – jason

+0

修正。変更 "ここで最初に適用することはできませんので、最初に適用されます。" 「最初のものはここでは適用できないので、それは適用する第2のものです」。 – jason

関連する問題