for WPF developers
Home Profile Tips 全記事一覧

Cast 拡張メソッドで型変換をおこなう

(2017/03/07 20:16:51 created.)

(2017/03/13 8:02:17 modified.)

Cast 拡張メソッドは object 型へのボックス化を用いた型変換をおこないます。

例えば次のような Person クラスとこれを基本クラスとした Member 派生クラスを定義します。

Person.cs
  1. namespace Tips_Linq
  2. {
  3.     using System;
  4.  
  5.     /// 
  6.     /// 人物データを表します。
  7.     /// 
  8.     public class Person
  9.     {
  10.         /// 
  11.         /// 氏名を取得または設定します。
  12.         /// 
  13.         public string Name { get; set; }
  14.  
  15.         /// 
  16.         /// 年齢を取得または設定します。
  17.         /// 
  18.         public int Age { get; set; }
  19.     }
  20. }
Member.cs
  1. namespace Tips_Linq
  2. {
  3.     /// 
  4.     /// メンバーデータを表します。
  5.     /// 
  6.     public class Member : Person
  7.     {
  8.         /// 
  9.         /// メンバー ID を取得または設定します。
  10.         /// 
  11.         public int ID { get; set; }
  12.     }
  13. }

Member クラスのコレクションを Person クラスのコレクションに型変換する例は次のようになります。

Program.cs
  1. namespace Tips_Linq
  2. {
  3.     using System;
  4.     using System.Collections.Generic;
  5.     using System.Linq;
  6.  
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             var members = GetMembers();
  12.             foreach (var member in members)
  13.             {
  14.                 Console.WriteLine(member.ID);
  15.             }
  16.  
  17.             var people = members.Cast<Person>();
  18.             foreach (var person in people)
  19.             {
  20.                 Console.WriteLine(person.Name);
  21.             }
  22.  
  23.             Console.ReadKey();
  24.         }
  25.  
  26.         /// 
  27.         /// メンバーコレクションの列挙子を取得します。
  28.         /// 
  29.         /// 
  30.         static IEnumerable<Member> GetMembers()
  31.         {
  32.             yield return new Member() { ID = 1, Name = "田中 淳平" };
  33.             yield return new Member() { ID = 2, Name = "鈴木 ほのか" };
  34.             yield return new Member() { ID = 3, Name = "小池 哲司" };
  35.             yield return new Member() { ID = 4, Name = "恩田 進" };
  36.             yield return new Member() { ID = 5, Name = "中津山 亜希子" };
  37.         }
  38.     }
  39. }


Cast 拡張メソッドで注意しなけらばいけないことは、ボックス化を使っていることです。つまり単純な数値型のキャスト変換はできません。例えば次のようなコードでは実行時に例外が発生します。

Program.cs
  1. namespace Tips_Linq
  2. {
  3.     using System;
  4.     using System.Linq;
  5.  
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             var doubles = new double[] { 0.1, 1.1, 2.1 };
  11.             Console.WriteLine("コレクションの要素は {{ {0} }} です。", string.Join(", ", doubles));
  12.  
  13.             var ints = doubles.Cast<int>();
  14.             Console.WriteLine("コレクションの要素は {{ {0} }} です。", string.Join(", ", ints));
  15.  
  16.             Console.ReadKey();
  17.         }
  18.     }
  19. }


ボックス化およびボックス化解除によって値型をキャストできないというのは言語仕様で、下記 URL にもその説明があります。

https://msdn.microsoft.com/ja-jp/library/b95fkada%28v=vs.80%29.aspx

数値型をキャストしたい場合は Select 拡張メソッドなどを使いましょう。

また、同様に型が変換される OfType 拡張メソッドがありますが、こちらは型によるフィルタリングをおこなう機能であり、すべての要素が指定された型になるわけではありません。詳しくは「OfType 拡張メソッドで型によるフィルタリングをおこなう」を参照してください。