私はこれも機能することに気づきました:
MessageBox.Show("number of things in the report are " + myHashSetVariable.Count);
myHashSetVariable.Count.ToString()を使用する必要があるという印象を受けました。
VS2010でのコンパイラ/インタプリタの改善のようなものですか?VS2010Proを使用しています
私はこれも機能することに気づきました:
MessageBox.Show("number of things in the report are " + myHashSetVariable.Count);
myHashSetVariable.Count.ToString()を使用する必要があるという印象を受けました。
VS2010でのコンパイラ/インタプリタの改善のようなものですか?VS2010Proを使用しています
まず、これはとは何の関係もありませんMessageBox.Show
。これは、+
オペレーターと関係があります。文字列+オブジェクトの結果は文字列に等しくなります。
言語の+演算子には多くのオーバーロードがあります(ユーザー定義型用に独自のオーバーロードを追加することもできます)。object
パラメータとしてをとるのは、operator+(string, object)
との2つだけoperator+(object, string)
です。どちらの場合も、オペレーターの実装の本体はパラメーターを呼び出しToString
てから、結果を生成するために使用します。object
string.Concat
変数は整数であり、最初のパラメーターとしてoperator+
withを使用しているため、他の候補string
とは一致しません。operator+(string, object)
ToStringは、メッセージ内の文字列リテラルを省略できることを確認するために暗黙的に呼び出されます。次に、コンパイルエラーを取り除くために、ToStringを明示的に呼び出す必要があります。
MessageBox.Show(myHashSetVariable.Count); //This gives the error
この方法で同じことを行うことができます:
int intval = 5;
string blah = "This is my string" + intval;
ToString()
そこで暗黙的に呼び出されます。ただし、コードをより明確にするために、明示的に呼び出すことは理にかなっています。
Servyはそれを正しく理解しています。文字列の連結と暗黙的な変換のトピックをさらに理解するのに役立つ可能性のあるいくつかのリンクと例を次に示します。
C#言語仕様セクション7.7.4加算演算子は次のように述べています。
二項+演算子は、一方または両方のオペランドが文字列型の場合に文字列連結を実行します。[...]文字列以外の引数は、オブジェクト型から継承された仮想ToStringメソッドを呼び出すことにより、文字列表現に変換されます。
int事前定義型の単純なケースでは、仕様に従ってint.ToString()が呼び出されています。ただし、ユーザー定義型を使用している場合は、文字列への暗黙的な変換に遭遇する可能性もあります( 6.4.3ユーザー定義の暗黙的な変換の詳細)。
実験するには、MessageBox.Show(string)を模倣するメソッドを定義します。Console.WriteLineを直接呼び出さないことが重要です。これは、Write(Int32)を含む多数のWriteのオーバーロードを提供するためです。
static void Write(string s)
{
Console.WriteLine(s);
}
そして、いくつかのユーザー定義クラス:
まず、オーバーライドや変換のない空のクラス。
class EmptyClass {
}
そして、Object.ToStringをオーバーライドするクラス。
class ToStringOnly {
public override string ToString() {
return "ToStringOnly";
}
}
文字列への暗黙の変換を示す別のクラス:
class ImplicitConversion {
static public implicit operator string(ImplicitConversion b) {
return "Implicit";
}
}
そして最後に、クラスが暗黙の変換を定義し、 Object.ToStringをオーバーライドするとどうなるのだろうか。
class ImplicitConversionAndToString {
static public implicit operator string(ImplicitConversionAndToString b) {
return "Implicit";
}
public override string ToString() {
return "ToString";
}
}
暗黙の変換のテスト:
// Simple string, okay
Write("JustAString"); // JustAString
// Error: cannot convert from 'int' to 'string'
//Write(2);
// EmptyClass cannot be converted to string implicitly,
// so we have to call ToString ourselves. In this case
// EmptyClass does not override ToString, so the base class
// Object.ToString is invoked
//Write(new EmptyClass()); // Error
Write(new EmptyClass().ToString()); // StackOverflowCSharp.Program+EmptyClass
// implicit conversion of a user-defined class to string
Write(new ImplicitConversion()); // Implicit
// while ToStringOnly overrides ToString, it cannot be
// implicitly converted to string, so we have to again
// call ToString ourselves. This time, however, ToStringOnly
// does override ToString, and we get the user-defined text
// instead of the type information provided by Object.ToString
//Write(new ToStringOnly()); // ERROR
Write(new ToStringOnly().ToString()); // "ToStringOnly"
そして、より適切なのは、文字列連結のテストです。
// Simple string
Write("string"); // "string"
// binary operator with int on the right
Write("x " + 2); // "x 2"
// binary operator with int on the left
Write(3 + " x"); // "3 x"
// per the specification, calls Object.ToString
Write("4 " + new EmptyClass()); // "4 StackOverflowCSharp.Program+EmptyClass"
// the implicit conversion has higher precedence than Object.ToString
Write("5 " + new ImplicitConversion()); // "5 Implicit"
// when no implicit conversion is present, ToString is called, which
// in this case is overridden by ToStringOnly
Write("6 " + new ToStringOnly()); // "6 ToStringOnly"
そして、暗黙の変換を定義し、Object.ToString()をオーバーライドするクラスですべてを封印するには、次のようにします。
// In both cases, the implicit conversion is chosen
Write( new ImplicitConversionAndToString() ); // "Implicit"
Write( "8: " + new ImplicitConversionAndToString()); // 8: Implicit