型を変換するには2つのやり方があります。
()でキャストする方法とas演算子を使う方法です。
object obj = "hoge";
string fuga = (string)obj;
string fuga = obj as string
機能的な違いとしては以下になります。
cast | as | |
キャストできない時 | System.InvalidCastException | null |
キャストできる型 | 参照型と値型 | 参照型のみ |
asは例外を発生しないという点と、int等の値型は使えないという2点だけ覚えればOKです。
asはユーザ定義の変換演算子も呼ばれません。
値型とはint, double, DateTime等です。
間違いやすいですがstringは参照型です。(とはいえstringには中身を変更するメソッド自体が存在せず、変更しているように見えて新たなオブジェクトを作るため、値型のように振る舞う)
使い分け
C#は例外発生時の処理が重いので例外を含んだ処理を書く場合、as演算子を使った方が速いです。
一方でas演算子だと例外が出ずnullになるので、本当の例外を拾いにくくなります。
・構造的に()でキャストができることが明白な場合、
・必ずキャストできる値がくる前提で組まれている箇所の場合、
()でキャストして、本当の例外を InvalidCastException で拾うのが良いと思います。
・逆に構造的にキャストできるかどうか分からない場合、
・キャストできるものだけ処理したい場合、
asでキャストして!null条件で処理させるのがいいと思います。
処理の流れとして異物は無視するという処理なのか、キャストできないハズがないのできちんと例外として拾いたいのか、で使いわけたいですね。
is演算子
is演算子は型チェックに用いられますが、C#7.0以降では変換もできます。
as演算子で変換する場合と比べてnullチェックを飛ばせるので短く書けます。
object hoge = "fuga1";
if(hoge is string fuga2)
{
Console.WriteLine( fuga2 )
};
hoge is stringがTrueの時、string型の変数fuga2に変換されます。
この変数fuga2のスコープはifステートメント内のみに限定される。
がしかし、以下のような使い方をした場合、if文の外でも使えてしまう。
if (!(sender is DataGrid dataGrid))
{
return;
}
if (dataGrid.SelectedIndex == -1)
{
return;
}
コメント