
C#のas演算子とは?キャストとの違いについて解説
as演算子は参照型変数をダウンキャストする時に利用する演算子です。
キャスト演算子()と似ており混同してしまう場合もあるので、キャスト演算子()との違いやアップキャストとダウンキャストの関係性について、詳しく解説していきます。
- PG
- クラス変数を、そのクラスが継承しているクラス型に変換したらコンパイルエラーになりました。
- PL
- そんなときはas演算子を使えば解決しますよ。キャスト演算子()と似ているため、違いも一緒に学んでいきましょう!
目次
C#のas演算子とは?
as演算子は、参照型変数をダウンキャストするときに用いる演算子のことです。
それぞれについて詳しく解説していきましょう。
参照型変数とは?
参照型変数はクラス変数とも呼ばれ、インスタンスの参照先を格納している変数です。
1 |
例:Classgata sansyo←参照型変数 = new Classgata(); |
通常よく使われるintやcharなどの変数は値型変数とも呼ばれ、変数自身が値そのものを格納しています。
そのため、値型変数に変更が加えられた場合はその値型変数の値が変更されます。
一方、参照型変数は自分自身に値を格納しているわけではなく、インスタンスの参照先を格納しているため、参照型変数に変更を加えられた場合は参照先のインスタンスが変更されます。
下記コードのように参照型変数Aの値が変更されたとき、同じインスタンスを参照している参照型変数Bの値も変わっていることが確認できるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; class class1 { public static void Main(){ class2 A = new class2(); class2 B = A; Console.WriteLine("変更前:A.Atai = " + A.atai); Console.WriteLine("変更前:B.Atai = " + B.atai); A.atai = 2; Console.WriteLine("Aを変更:A.Atai = " + A.atai); Console.WriteLine("Aを変更:B.Atai = " + B.atai); B.atai = 3; Console.WriteLine("Bを変更:A.Atai = " + A.atai); Console.WriteLine("Bを変更:B.Atai = " + B.atai); } } class class2 { public int atai = 1; } |
1 2 3 4 5 6 |
変更前:A.Atai = 1 変更前:B.Atai = 1 Aを変更:A.Atai = 2 Aを変更:B.Atai = 2 Bを変更:A.Atai = 3 Bを変更:B.Atai = 3 |
ダウンキャストとは?
ダウンキャストは親クラス型の参照型変数から子クラス型へキャストすることを指しますが、アップキャストされていることが前提です。
アップキャストとはダウンキャストの対のこと。
子クラス型の参照型変数を、子クラスが継承している親クラスの型に変更することを言います。
以下のコードを見てください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System; class Fruits { public string azi = "oisii"; } class Apple : Fruits { public new string azi = "amai"; } class Lemon : Fruits { public new string azi = "suppai"; } class taberu { public static void Main() { Fruits fruits; Apple apple = new Apple(); Lemon lemon = new Lemon(); Console.WriteLine("Apple型:" + apple.azi); Console.WriteLine("Lemon型:" + lemon.azi); //appleをfruits型にアップキャスト fruits = apple; Console.WriteLine("appleをFruits型にアップキャスト:" + fruits.azi); //lemonをfruits型にアップキャスト fruits = lemon; Console.WriteLine("lemonをfruits型にアップキャスト:" + fruits.azi); } } |
1 2 3 4 |
Apple型:amai Lemon型:suppai appleをFruits型にアップキャスト:oisii lemonをfruits型にアップキャスト:oisii |
アップキャストを行う場合は演算子を使わなくても正常に動作するため、一見するとただ数を更新しているように見えますが、裏で親クラス型から子クラス型へアップキャストが行われています。
ダウンキャストはその逆で、アップキャストされた参照型変数を子クラス型に戻すことを言います。
しかし、アップキャストのように暗黙的に行うことはできません。
アップキャストされたインスタンスは子クラス型から生成されたもので、あくまでも親クラス型です。
親クラス自体が子クラスを格納しているわけでは無いので、型が合わずコンパイルエラーとなるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; class Fruits { public string azi = "oisii"; } class Apple : Fruits { public string azi = "amai"; } class Lemon : Fruits { public string azi = "suppai"; } class taberu { public static void Main() { Fruits fruits; Apple apple = new Apple(); Lemon lemon = new Lemon(); //appleをfruits型にアップキャスト→成功 fruits = apple; //fruitsをapple型にダウンキャスト→失敗 apple = fruits; //lemonをfruits型にアップキャスト→成功 fruits = lemon; //fruitsをlemon型にダウンキャスト→失敗 lemon = fruits; } } |
1 2 |
test.cs(50,9): error CS0266: Cannot implicitly convert type `Fruits' to `Apple'. An explicit conversion exists (are you missing a cast?) test.cs(60,9): error CS0266: Cannot implicitly convert type `Fruits' to `Lemon'. An explicit conversion exists (are you missing a cast?) |
正しくダウンキャストをするには、変換先の型を明示的に指定しなければなりません。
このダウンキャスト時に使われるのが、as演算子です。
as演算子の使用方法
as演算子は以下のように使用します。
1 |
【変換先の型の参照型変数】 = 【型変換したい参照型変数】 as 【変換先の型名】 |
先ほどコンパイルエラーになってしまったダウンキャストのコードを、as演算子を使用して変換してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System; class Fruits { public string azi = "oisii"; } class Apple : Fruits { public string azi = "amai"; } class Lemon : Fruits { public string azi = "suppai"; } class taberu { public static void Main() { Fruits fruits; Apple apple = new Apple(); Lemon lemon = new Lemon(); //appleをfruits型にアップキャスト→成功 fruits = apple; //fruitsをapple型にダウンキャスト→成功 apple = fruits as Apple; //lemonをfruits型にアップキャスト→成功 fruits = lemon; //fruitsをlemon型にダウンキャスト→成功 lemon = fruits as Lemon; Console.WriteLine("fruitsをapple型にダウンキャスト:" + apple.azi); Console.WriteLine("fruitsをlemon型にダウンキャスト:" + lemon.azi); } } |
1 2 |
fruitsをapple型にダウンキャスト:amai fruitsをlemon型にダウンキャスト:suppai |
コンパイルエラーにならずダウンキャストに成功していることが確認できます。
as演算子とキャスト演算子()の違い
as演算子と同じく型変換をするときに用いられるキャスト演算子()との違いは、「型変換できない時に返される内容」です。
キャスト演算子()を使用し、型変換ができなかった場合は例外が返ります。
一方、as演算子はというと、型変換ができなかった場合はnullが返ります。
キャスト演算子()もダウンキャストを行うことは可能ですが、失敗時には例外が返ってきてしまうので、例外対応を事前に用意できるas演算子の使用を推奨します。
しかしnullが返るということは、intやdoubleなどのnull値が入らない型には使用できません。
キャスト演算子()はintからdoubleなどの型変換で使用し、as演算子は参照型変数の型変換に使用するという使い分けが必要でしょう。
- PG
- as演算子はクラス変数のダウンキャスト時に最適な演算子であることが理解できました。
- PL
- 参照型変数の型変換ができれば、クラス間の処理の幅が広がります。上手く使いこなしましょう!
アップキャストは暗黙的に、ダウンキャストはas演算子で明示的に
ダウンキャスト時にキャスト演算子()を使用したり、暗黙的に実行しようとしたりすると、思わぬ例外処理が投げられてしまう場合がありますので注意が必要です。
as演算子はアップキャストやキャスト演算子()とも非常に密な関係性にあるので、違いをしっかりと理解しましょう。