806

次のコードを検討してください。

void Handler(object o, EventArgs e)
{
   // I swear o is a string
   string s = (string)o; // 1
   //-OR-
   string s = o as string; // 2
   // -OR-
   string s = o.ToString(); // 3
}

3種類のキャスティングの違いは何ですか(3つ目はキャスティングではありませんが、意図はあります)。どちらを優先する必要がありますか?

4

16 に答える 16

932
string s = (string)o; // 1

でない場合はInvalidCastExceptionをスローします。それ以外の場合は、がであっても、に割り当てます。ostringosonull

string s = o as string; // 2

ifがaでない場合、またはifがである場合nullに割り当てます。このため、値型で使用することはできません(その場合、演算子は戻ることができません)。それ以外の場合は、に割り当てます。sostringonullnullos

string s = o.ToString(); // 3

の場合、NullReferenceExceptionoが発生しnullます。タイプに関係なく、にo.ToString()戻るものをすべて割り当てます。so


ほとんどの変換には1を使用します。これは単純で簡単です。何かが適切なタイプでない場合、私は通常例外が発生することを期待しているので、私はほとんど2を使用しない傾向があります。私は、エラーコードを使用する不適切に設計されたライブラリでこのreturn-nullタイプの機能の必要性を見ただけです(たとえば、例外を使用する代わりにreturn null = error)。

3はキャストではなく、単なるメソッド呼び出しです。非文字列オブジェクトの文字列表現が必要な場合に使用します。

于 2008-09-25T10:16:26.240 に答える
396
  1. string s = (string)o;何かが 絶対に別のものであるべきときに使用します。
  2. string s = o as string;何か別のものである可能性がある場合に使用します。
  3. string s = o.ToString();それが何であるかは気にせず、利用可能な文字列表現を使用したい場合に使用します。
于 2008-09-25T10:31:28.453 に答える
32

それは本当にあなたが文字列であるかどうかを知っているかどうかo、そしてあなたがそれで何をしたいかに依存します。あなたのコメントがo本当に本当に文字列であることを意味するなら、私はストレート(string)oキャストを好むでしょう-それは失敗する可能性は低いです。

ストレートキャストを使用する最大の利点は、失敗すると、InvalidCastExceptionが発生することです。これにより、何がうまくいかなかったかがわかります。

as演算子を使用すると、が文字列でない場合はosに設定されnullます。これは、不明でテストしたい場合に便利ですs

string s = o as string;
if ( s == null )
{
    // well that's not good!
    gotoPlanB();
}

ただし、そのテストを実行しない場合は、後で使用sしてNullReferenceExceptionがスローされます。ほぼすべての行が変数を逆参照し、変数をスローする可能性があるため、これらはより一般的であり、実際に発生すると追跡するのがはるかに困難になる傾向があります。一方、値型(任意のプリミティブ、またはDateTimeなどの構造体)にキャストしようとしている場合は、ストレートキャストを使用する必要があります-は機能しasません。

文字列に変換する特殊なケースでは、すべてのオブジェクトにが含まれているため、がnullでなく、メソッドが希望どおりに機能すると思わToStringれる場合は、3番目のメソッドで問題ない可能性があります。oToString

于 2008-09-25T10:16:50.593 に答える
9

キャストできる型がわかっている場合は、C スタイルのキャストを使用します。

var o = (string) iKnowThisIsAString; 

明示的な型強制を実行できるのは、C スタイルのキャストのみであることに注意してください。

それが目的のタイプであるかどうかわからず、そうである場合はそれを使用する場合は、次のキーワードを使用します。

var s = o as string;
if (s != null) return s.Replace("_","-");

//or for early return:
if (s==null) return;

asは型変換演算子を呼び出さないことに注意してください。オブジェクトが null ではなく、ネイティブに指定された型である場合にのみ、非 null になります。

文字列にキャストできない場合でも、ToString() を使用して、オブジェクトの人間が判読できる文字列表現を取得します。

于 2008-09-25T10:41:43.170 に答える
7

FindControl メソッドを使用する場合、as キーワードは asp.net で有効です。

Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
     ...
}

objectこれは、直接キャストの場合のようにキャストするのではなく、型付き変数を操作できることを意味します。

object linkObj = this.FindControl("linkid");
if (link != null)
{
     Hyperlink link = (Hyperlink)linkObj;
}

大したことではありませんが、コード行と変数の割り当てを節約でき、さらに読みやすくなります。

于 2008-09-25T11:17:27.030 に答える
6

'as'は'is'に基づいています。これは、オブジェクトがポリモーフィックに互換性があるかどうか(基本的にキャストが可能かどうか)を実行時にチェックし、チェックが失敗した場合はnullを返すキーワードです。

これら2つは同等です:

'as'の使用:

string s = o as string;

'is'の使用:

if(o is string) 
    s = o;
else
    s = null;

逆に、cスタイルのキャストは実行時にも作成されますが、キャストを作成できない場合は例外がスローされます。

重要な事実を追加するだけです:

'as'キーワードは、参照型でのみ機能します。できません:

// I swear i is an int
int number = i as int;

そのような場合は、キャストを使用する必要があります。

于 2008-09-25T10:15:32.670 に答える
6

このページで実行された実験によると: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as

(このページには「不正なリファラー」エラーが時々表示されるため、表示された場合は更新してください)

結論として、「as」演算子は通常、キャストよりも高速です。時には何倍も速く、時にはかろうじて速くなります。

個人的には「as」の方が読みやすいです。

したがって、高速で「安全」(例外をスローしない) であり、読みやすい可能性があるため、常に「as」を使用することをお勧めします。

于 2010-08-15T18:36:54.803 に答える
5

2 は、派生型へのキャストに役立ちます。

aが動物であるとします:

b = a as Badger;
c = a as Cow;

if (b != null)
   b.EatSnails();
else if (c != null)
   c.EatGrass();

最小限のキャストでフィードを取得します。

于 2008-09-25T10:31:39.170 に答える
4

"(string)o" は、直接キャストがないため、InvalidCastException が発生します。

「o as string」は、例外がスローされるのではなく、s が null 参照になります。

「o.ToString()」は、それ自体はいかなる種類のキャストでもありません。オブジェクトによって実装されるメソッドであり、したがって、.net 内のすべてのクラスによって何らかの方法で「何かを行う」インスタンスでそれが呼び出され、文字列を返すクラス。

文字列に変換するために、 Convert.ToString(someType instanceOfThatType) もあるということを忘れないでください。someType は一連の型の 1 つであり、基本的にはフレームワークの基本型です。

于 2008-09-25T10:17:50.810 に答える
3
string s = o as string; // 2

ダブルキャスティングのパフォーマンスペナルティを回避するため、推奨されます。

于 2008-09-25T11:05:43.113 に答える
3

私が何かを追加する可能性がある場合、与えられたすべての答えは良いです: 文字列のメソッドとプロパティ (ToLower など) を直接使用するには、次のように書くことはできません:

(string)o.ToLower(); // won't compile

あなただけが書くことができます:

((string)o).ToLower();

しかし、代わりに次のように書くこともできます:

(o as string).ToLower();

オプションのas方が読みやすいです (少なくとも私の意見では)。

于 2014-04-03T14:28:13.900 に答える
0

null になる可能性のあるもの (任意の型) の文字列表現を取得しようとするときは、以下のコード行を好みます。コンパクトで、ToString() を呼び出し、null を正しく処理します。o が null の場合、s には String.Empty が含まれます。

String s = String.Concat(o);
于 2012-06-23T01:31:48.503 に答える