2012-12-11 5 views
31

このコードがどのようにフォローアウト出力を生成するか説明する人は気になりますか?オプションのパラメータとメソッドオーバーライドとオプションのパラメータ

using System; 

namespace ConsoleApplication1 
{ 
    class Test 
    { 
     public override string ToString() { return "ToString override"; } 
     public string ToString(string optional = "") 
      { return String.Format("ToString with optional parameter {0}", optional); } 
    } 

    class Test2 
    { 
     public new string ToString() { return "ToString new"; } 
     public string ToString(string optional = "") 
      { return String.Format("ToString with optional parameter {0}", optional); } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Test one = new Test(); 
      Test2 two = new Test2(); 
      Console.WriteLine(one); 
      Console.WriteLine(one.ToString()); 
      Console.WriteLine(one.ToString("foo")); 
      Console.WriteLine("--"); 
      Console.WriteLine(two); 
      Console.WriteLine(two.ToString()); 
      Console.WriteLine(two.ToString("bar")); 
      Console.ReadKey(); 
     } 
    } 
} 

ToStringメソッドのオーバーライド

ToStringメソッドオプションのパラメータfooで

のToString

-

ConsoleApplication1.Test2

ます。Console.WriteLine(1)

これはWriteLine(object)を使用します。一般的な関心がありますように、ここでは迅速なバージョンだ、

+3

あなたはどのラインを理解していませんか? (すべてのことについて詳しく調べるのは面倒です)。 –

+0

基本的には、コンパイラが同じメソッドを選択するのは、同じシグネチャがあるからです。 – pneuma08

+1

彼らは同じシグネチャを持っていません。また、*あなたが立ち往生している行を*書くと助けになります。どのくらいあなたは過負荷の解決が機能するか理解しようとしましたか?ところで、C#4.5のようなものはありません。 –

答えて

49

オーケーオプションのパラメータバーで新しい

ToStringメソッドのtoStringオーバーロードすると、object.ToString()仮想メソッドが実行され、Oneにオーバーライドされます。したがって、出力はToString override

ます。Console.WriteLine(one.ToString())

これはOneを見て、方法は、新たに宣言されたメソッドがいるでしょう - 割り引くオーバーライドを。ちょうど1つのそのような方法が適用可能です - オプションのパラメータを持つもの。つまり、デフォルト値を使用して実行され、結果はToString with optional parameterになります。

再び同じConsole.WriteLineを(one.ToString( "foo" という))

が、今回は、コンパイラは、コンソールので、ToString with optional parameter foo

、デフォルト値を使用する必要はありません。 WriteLine(2)

これもまた、仮想object.ToString()メソッドをWriteLine(object)から呼び出します。このメソッドはオーバーライドされていないため、型の名前を返すデフォルトの実装が使用され、結果はConsoleApplication1.Test2になります。

ます。Console.WriteLine(two.ToString())

コンパイラはオーバーライド仮想メソッドではありませんTwoで宣言されたすべての方法を見ます。この場合、パラメータのないメソッドとオプションのパラメータを持つメソッドの2つのメソッドがあります。基本クラスメソッドをオーバーライドするのではなく、newであるため、パラメータのないものが含まれています。

コンパイラは任意のパラメータを入力する必要がないメソッドを呼び出すため、パラメータのないメソッドは「より良い」候補とみなされます。従って、出力ToString new

あります。Console.WriteLine(two.ToString( "バー"))

はここでも、コンパイラはが仮想メソッドをオーバーライドしていないTwoで宣言されたすべての方法を見ます。この場合、2つの方法がありますが、パラメータのないものは適用されず、オプションのパラメータだけが残ります。それはとにかく引数を持っているとして、コンパイラは、使用ここで、オプションのパラメータのデフォルト値には必要ありません...ので、出力はずっとこれについてについてはToString with optional parameter bar

で、C#言語仕様を読んで - か途中の家については、article on overloadingを参照してください。

+3

本当に退屈ではありますが、有益で、書き留めてくれてありがとう –

+0

良いものジョン(いつものように)。私は徐々にそれをすべて取り組んでいた。主な潜在的な驚き点は、オブジェクトの 'ToString'ではなく' object.ToString() 'を使用し、継承されたメソッドに新しく定義されたメソッドを好んでいる点です。 – Chris

+71

Good Guy Jon Skeet:「すべてのことについて詳しく説明するのは面倒です」と言い、すべてについて詳しく説明します。 – Rawling

関連する問題