C#のisとasとは?アップキャストとダウンキャスト・C# 7.0からはisでキャスト処理も同時に行える
- システム
エンジニア - C#のisとasとはなんですか?
- プロジェクト
マネージャー - C#のisとas、それぞれの使用方法を紹介します。
C#のisとasとは?基礎から解説します
C#のisとasとは?
C#のisとasは、キャストに関連した演算子です。そもそもキャストとは何なのでしょうか?例を挙げて説明しましょう。
以下のようなプログラムを記述するとします。このプログラムでは、testという文字列をいったんobject型にして、また文字列に戻して表示しようとしています。このように型を変換することをキャストと言います。
1
2
3
4
5
|
string test = "テスト";
object o = test;
string str = o;
Console.WriteLine(str);
|
しかしこれを入力すると、「 string str = o;」の箇所で「型’object’を’string’に暗黙的に変換できません。明示的な変換が存在します」というエラーが出ます。
アップキャストとダウンキャスト
stringのtestをobjectのoにするのはエラーがでないのに、その逆はエラーになるのです。これはなぜでしょうか?それは、stringをobjectにするのはアップキャストで、objectをstringにするのはダウンキャストだからです。
stringという型はobjectという型の下位のサブクラスです。つまりstringは子で、objectはその親になります。stringからobjectのように子から親に変換するのはアップキャスト、その逆はダウンキャストと言います。
ダウンキャストは明示的に行う
C#の子クラスは親クラスが実装している機能を全て含むため、「暗黙的に」アップキャストしても問題なく動作します。そのためエラーにはなりません。しかし子クラスは親クラスに無い機能があるので、ダウンキャストの場合は「明示的に」キャストする必要があります。
明示的にダウンキャストするには、以下のC#サンプルのように”(クラス名)”を変換時に追加すれば可能です。こうすればエラーにはなりません。
1
2
3
4
|
string test = "テスト";
object o = test;
string str = (string)o; // 明示的なキャスト
Console.WriteLine(str);
|
これを実行すると「テスト」と表示されます。
ダウンキャストの危険性
では明示的にダウンキャストすれば、常に問題はおこらないのでしょうか?実際はそうではありません。以下のC#サンプルを実行してみましょう。
1
2
3
4
5
|
DateTime dt = new DateTime();
object o = dt;
string str = (string)o;
Console.WriteLine(str);
|
実行すると、「Unhandled exception. System.InvalidCastException: Unable to cast object of type ‘System.DateTime’ to type ‘System.String’.」という例外が「string str = (string)o;」の箇所で発生してしまいます。
ダウンキャストの例外発生を防ぐには?
DateTimeクラスとStringクラスは親子関係でないため、ダウンキャストできず例外が発生してしまうのです。このようなことが無いように気を付ける必要があります。
しかし以下のC#サンプルのように、渡されるフィールドのクラスがわからない場合もあります。こういった場合はどのようにして例外を防げばいいのでしょうか。
1
2
3
4
5
6
|
static void DispObject(object o)
{
string str = (string)o; // oをstringにキャストできるかどうかはわからない
Console.WriteLine(str);
}
|
例外をキャッチする方法
一つのやり方としては、例外が発生したらキャッチする方法です。以下のC#サンプルを実行すると「stringにダウンキャストできません」と表示されて、例外がcatch内で処理されていることがわかります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
static void Main(string[] args)
{
DateTime dt = new DateTime();
DispObject(dt);
}
static void DispObject(object o)
{
try
{
string str = (string)o;
Console.WriteLine(str);
}
catch (InvalidCastException)
{
Console.WriteLine("stringにダウンキャストできません");
}
}
|
isを使う方法
しかし実際は、そもそも例外を発生させたくない、発生するかどうかを事前に判断したいと思うケースが多いでしょう。その時に役立つのがis演算子なのです。
以下のC#サンプルのやり方で事前に型を判定することができます。結果は「stringにダウンキャストできません」と表示されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
static void DispObject(object o)
{
if (o is string) // isでキャストできるか判定する
{
string str = (string)o;
Console.WriteLine(str);
}
else
{
Console.WriteLine("stringにダウンキャストできません");
}
}
|
C# 7.0からはisでキャスト処理も同時に行える
C# 7.0からはisで判定だけでなく、キャストできる場合はキャストした変数を宣言することも同時にできるようになりました。
以下のC#サンプルはここまでのサンプルにあった「 string str = (string)o;」が不要になっています。
1
2
3
4
5
6
7
8
9
10
11
12
|
static void DispObject(object o)
{
if (o is string str) // 判定と同時にstr変数を宣言できる
{
Console.WriteLine(str);
}
else
{
Console.WriteLine("stringにダウンキャストできません");
}
}
|
asを使う方法
今回のテーマのもう一方のas演算子についても解説します。ダウンキャストによる例外発生は、このasでも防ぐことが出来ます。
以下のC#サンプルを実行してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
|
static void Main(string[] args)
{
DateTime dt = new DateTime();
DispObject(dt);
}
static void DispObject(object o)
{
string str = o as string;
Console.WriteLine(str);
}
|
asで例外発生は抑えられる
上のC#サンプルはDispObjectメソッドにDateTime型が渡されています。これをasを使用してstringにキャストしています。ところが実行結果は何も表示されません。
strはどうなっているのでしょうか?このサンプルのDispObjectを、以下のように修正してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
static void DispObject(object o)
{
string str = o as string;
if (str!=null)
{
Console.WriteLine(str);
}
else
{
Console.WriteLine("stringにダウンキャストできません");
}
}
|
isとasの使い分け
上のC#サンプルの結果は「stringにダウンキャストできません」になります。つまり、asでキャストを行った場合、キャストできないとnullが代入されるということです。
しかしasで例外発生を抑えられても、キャストした結果がnullになるのは困るというケースも多いでしょう。その場合は、asよりisを利用するケースの方が多くなるでしょう。
- システム
エンジニア - C#のisとasの使い方が分かりました。
- プロジェクト
マネージャー - C#のisとasを使い分けなど理解を深めて、実際にコードを書いてみましょう。
C#のisとasを活用して例外発生を防ごう
C#のisとasについて解説しましたが、ご理解頂けたでしょうか。どちらの演算子も例外を防ぐのにとても有効です。適切に使用して、エラーの無い高品質なプログラムを作り上げましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)