web-dev-qa-db-ja.com

C#での.ToStringと「as string」の違い

次の2つのステートメントを使用することの違いは何ですか?最初の「文字列として」は型キャストであり、2番目のToStringは入力を文字列に変換するメソッドの実際の呼び出しであるように見えますか?ある洞察を探しています。

Page.Theme = Session["SessionTheme"] as string;
Page.Theme = Session["SessionTheme"].ToString();
64
jaywon

_Session["SessionTheme"]_がstringでない場合、_as string_はnullを返します。

.ToString()は、オブジェクトのToString()メソッドを呼び出して、他の型を文字列に変換しようとします。ほとんどの組み込み型の場合、これは文字列に変換されたオブジェクトを返しますが、特定の.ToString()メソッドを持たないカスタム型の場合、オブジェクトの型の名前を返します。

_object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

string s = o1 as string;  // returns "somestring"
string s = o1.ToString(); // returns "somestring"
string s = o2 as string;  // returns null
string s = o2.ToString(); // returns "1"
string s = o3 as string;  // returns null
string s = o3.ToString(); // returns "System.Object"
string s = o4 as string;  // returns null
string s = o4.ToString(); // throws NullReferenceException
_

留意すべきもう1つの重要なことは、オブジェクトがnullの場合、.ToString()を呼び出すと例外がスローされるが、_as string_はnullを返すだけであることです。

94

asキーワードは、基本的にオブジェクト内部のMSILオペコードisを使用して、オブジェクトisinstが型のインスタンスであるかどうかをチェックします。存在する場合は、オブジェクトへの参照を返し、そうでない場合はnull参照を返します。

It doesは、多くの人が言っているように、キャストを実行しようとはしていません。これは、何らかの例外処理を意味します。そうではない。

ToString()は、オブジェクトのToString()メソッドを呼び出します。これは、クラス(ほとんどの組み込み型では文字列への変換を実行する)によって実装されたカスタムメソッドです。基本クラスobjectの1つで、型情報を返します。

13
Page.Theme = Session["SessionTheme"] as string;

文字列にキャストしようとします

一方、

Page.Theme = Session["SessionTheme"].ToString;

tostringメソッドを呼び出します。これは実際には何でもかまいません。このメソッドはキャストしません。このオブジェクトの文字列表現を返す必要があります。

5
Oxymoron

まず、「any-object as string」と「any-object.ToString()」は、それぞれのコンテキストがまったく異なります。

string str = any-object as string;

1)これは、任意のオブジェクトを文字列型としてキャストし、任意のオブジェクトが文字列にキャストできない場合、このステートメントは例外をスローせずにnullを返します。
2)これはコンパイラーサービスです。
3)これは、文字列以外の他の型に対しても非常にうまく機能します。例:Employeeとして任意のオブジェクトとして実行できます。Employeeはライブラリで定義されたクラスです。

string str = any-object.ToString();  

1)これは、型定義からany-objectのToString()を呼び出します。 System.ObjectはToString()メソッドを定義するため、.Netフレームワークのすべてのクラスには、オーバーライドに使用できるToString()メソッドがあります。プログラマーは、any-objectクラスまたはstruct definationのToString()をオーバーライドし、any-objectの果たす役割と役割に応じて、any-objectの適切な文字列表現を返すコードを記述します。
2)Employeeクラスを定義し、Employeeオブジェクトの文字列表現を "FIRSTNAME-LASTNAME、EMP-CDOE"として返す可能性があるToString()メソッドをオーバーライドできます。

この場合、プログラマーはToString()を制御し、キャストまたは型変換とは関係がないことに注意してください。

問題をさらに混乱させるために、C#6.0は null-conditional operator を導入しました。したがって、これは次のように書くこともできます。

Page.Theme = Session["SessionTheme"]?.ToString();

これは、例外をスローせずにnullまたはToString()からの結果を返します。

3
Mike Lowery

Philippe Leybaertの受け入れられた答えを少し拡張しています。これらの3つを比較するリソースを見つけましたが、4つすべてを比較する説明を見つけたことがないからです。

  • _(string)obj_
  • _obj as string_
  • obj.ToString()
  • Convert.ToString(obj)
_object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;

Console.WriteLine((string)o1);           // returns "somestring"
Console.WriteLine(o1 as string);         // returns "somestring"
Console.WriteLine(o1.ToString());        // returns "somestring"
Console.WriteLine(Convert.ToString(o1)); // returns "somestring"
Console.WriteLine((string)o2);           // throws System.InvalidCastException
Console.WriteLine(o2 as string);         // returns null
Console.WriteLine(o2.ToString());        // returns "1"
Console.WriteLine(Convert.ToString(o2)); // returns "1"
Console.WriteLine((string)o3);           // throws System.InvalidCastException
Console.WriteLine(o3 as string);         // returns null
Console.WriteLine(o3.ToString());        // returns "System.Object"
Console.WriteLine(Convert.ToString(o3)); // returns "System.Object"
Console.WriteLine((string)o4);           // returns null
Console.WriteLine(o4 as string);         // returns null
Console.WriteLine(o4.ToString());        // throws System.NullReferenceException
Console.WriteLine(Convert.ToString(o4)); // returns ""
_

これらの結果から、objが文字列またはnullの場合、_(string)obj_と_obj as string_は互いに同じように動作することがわかります。それ以外の場合、_(string)obj_は無効なキャスト例外をスローし、_obj as string_は単にnullを返します。 obj.ToString()Convert.ToString(obj)も、objがnullの場合を除いて互いに同じように動作します。その場合、obj.ToString()はnull参照例外をスローしますConvert.ToString(obj)は空の文字列を返します。

だからここに私の推奨事項があります:

  • _(string)obj_は、文字列変数(nullを含む)に割り当てることができない型の例外をスローする場合に最適です。
  • _obj as string_は、例外をスローしたくない場合、および非文字列の文字列表現が必要ない場合に最適に機能します
  • obj.ToString()は、nullの例外をスローする場合に最適です
  • Convert.ToString(obj)は、例外をスローしたくなく、文字列以外の文字列表現が必要な場合に最適です
1
Kyle Delaney

_as string_チェックは、オブジェクトが文字列であることです。 nullでない場合は返されます。

ToString()の呼び出しは、実際にオブジェクトのToString()メソッドを呼び出します。

1
Oded

最初のものは、クラスが文字列または文字列から派生した場合、クラスを文字列として返します(失敗した場合はnullを返します)。

2番目は、クラスでToString()メソッドを呼び出します。

1
rein

実際、上記のコードを記述する最良の方法は次のことです。

if (Session["SessionTheme"] != null)
{
    Page.Theme = Session["SessionTheme"].ToString();
}

そうすれば、NullReferenceExceptionをキャストしないことがほぼ確実になります。

0
mortenbpost