第14章 インターフェイスの活用連載 改訂版 C#入門(4/4 ページ)

» 2002年11月20日 00時00分 公開
[川俣晶(http://www.autumn.org/)(株)ピーデー(http://www.piedey.co.jp/)]
前のページへ 1|2|3|4       

14-8 外部から条件を指定してソートする

 List 14-8の例は、ArrayListに格納されるインスタンス自身が、どう並べ替えられるべきかを知っている場合のサンプルである。しかし、ソート順がいつも決まっている場合ばかりとは限らない。例えば、住所録なら、名前順でソートしたいときや、住所順でソートしたいときがあるだろう。そういうケースでは、ソート順をクラスの外部で指定するという方法もある。この方法なら、さまざまなソート方法を準備しておき、それを切り替えながら利用できる。List 14-9はそれを実現した例である。

  1: using System;
  2: using System.Collections;
  3:
  4: namespace Sample009
  5: {
  6:   class ClassComparer : IComparer
  7:   {
  8:     public int Compare( object x, object y )
  9:     {
 10:       double dx = (double)x;
 11:       double dy = (double)y;
 12:       return (int)dx - (int)dy;
 13:     }
 14:   }
 15:   class Class1
 16:   {
 17:     [STAThread]
 18:     static void Main(string[] args)
 19:     {
 20:       ArrayList al = new ArrayList();
 21:       al.Add( 2.2 );
 22:       al.Add( 3.7 );
 23:       al.Add( 1.5 );
 24:       al.Add( 2.7 );
 25:       al.Add( 3.2 );
 26:       al.Add( 1.1 );
 27:       al.Sort( new ClassComparer() );
 28:       foreach( double d in al )
 29:       {
 30:         Console.WriteLine( d );
 31:       }
 32:     }
 33:   }
 34: }

List 14-9

 これを実行するとFig.14-9のようになる。

Fig.14-9

 List 14-9のサンプルでは、ちょっと変わった条件付けを行ってソートを行っている。つまり、実数をソートするのだが、順番は整数扱いで決めるというものだ。小数部は昇順に揃っていないが、整数だけは揃っているという変な状態を作り出している。これを実現するには、Sortメソッドの引数にIComparerインターフェイスの参照を渡す。27行目にその実例が記述されている。ここではClassComparerクラスのインスタンスが渡されているが、これにはIComparerが実装されているので、自動的にそれが取り出されて渡される。

 このIComparerは実装されなければ使えないので、IComparerを実装するクラスとして、6〜14行目にClassComparerクラスを定義している。IComparerは1つのメソッドCompareを含んでいるので、これを実装する。8行目の引数のx、yは、比較すべき2つのオブジェクトである。ここでは、実数がくるはずなので、10〜11行目のように、一度、doubleにキャストしてやる。そして、12行目で整数にキャストして比較する。この比較により、小さければ負数、同じなら0、大きければ正数を返すという条件が満たされる。

 以上により、27行目のSortメソッド実行時には、何度もCompareメソッドが呼ばれ、その結果に並べ替えが行われるというわけである。

14-9 国際化を意識した自動文字列化

 .NET Frameworkでは、どんなクラスもToStringというメソッドを持っている。どんなオブジェクトも、文字列に変換される必要がある場合、これが呼び出される。例えば、Console.WriteLineメソッドなどで出力するときに、自作クラスを指定しても、ToStringメソッドさえきちんと実装されていれば、適切な値が出てくるわけである。ここまでの機能は、単なる継承によって実現される。だが、インターフェイスを使うと、もうちょっと凝ったことができる。

 デフォルトのカルチャーが日本の日本語(ja-JP)である場合に、数値の1、2、3を、漢数字の一、二、三にする機能を記述してみよう。List 14-10はそれを実現する例である。

  1: using System;
  2: using System.Globalization;
  3:
  4: namespace Sample010
  5: {
  6:   class ClassSample : IFormattable
  7:   {
  8:     public int x;
  9:     public string ToString( string format, IFormatProvider formatProvider )
 10:     {
 11:       if( formatProvider is CultureInfo )
 12:       {
 13:         CultureInfo ci = (CultureInfo)formatProvider;
 14:         if( ci.Name == "ja-JP" )
 15:         {
 16:           switch( x )
 17:           {
 18:             case 1:
 19:               return "一";
 20:             case 2:
 21:               return "二";
 22:             case 3:
 23:               return "三";
 24:           }
 25:         }
 26:       }
 27:       return x.ToString();
 28:     }
 29:   }
 30:   class Class1
 31:   {
 32:     [STAThread]
 33:     static void Main(string[] args)
 34:     {
 35:       ClassSample cs = new ClassSample();
 36:       cs.x = 3;
 37:       Console.WriteLine( cs );
 38:     }
 39:   }
 40: }

List 14-10

 これを実行するとFig.14-10のようになる。

Fig.14-10

 では解説しよう。IFormattableとは、インスタンスを文字列で書式化する機能を提供するインターフェイスである。カルチャーの情報などを参照して、動作環境によって動作を変えることができる。例えば、日付などの処理に利用されるものである。アメリカなら「January」だが、日本では「一月」を出力する、というような場面で意味を持つ。

 IFormattableが持つメソッドはToStringだけである。このToStringは、すべてのクラスが持っているToStringとは異なり、9行目にあるとおり、2つの引数を持つ。最初の引数には、通貨などの条件を指定する文字列がくるが、ここでは無視している。2番目の引数には、Console.WriteLineメソッドなどから呼び出すときはカルチャー情報が渡されてくる。そこで、11行目で確認してから、13行目でキャストしてCultureInfoクラスのインスタンスとして扱う。このインスタンスのNameプロパティの値が「ja-JP」なら日本語環境で動いていることを示す。これらの条件を満たすときには、16〜24行目のように、数値の1〜3を漢数字として返している。どの条件にも当てはまらない場合は、27行目のように、引数のないToStringで文字列に変換しているが、これは、数値の123が文字列の「123」になるような単純な変換である。

 さて、これらのコードによって、37行目のように直接インスタンスをConsole.WriteLineに渡すと、Console.WriteLineメソッドの書式整形処理の一環として、9行目からのToStringメソッドが呼び出されるので、出力内容をカルチャー情報によって変化させることができるのである。

『新プログラミング環境 C#がわかる+使える』
 本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て一部分を転載したものです。

【本連載と書籍の関係について 】
 この書籍は、本フォーラムで連載した「C#入門」を大幅に加筆修正し、発行されたものです。連載時はベータ版のVS.NETをベースとしていましたが、書籍ではVS.NET製品版を使ってプログラムの検証などが実施されています。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。

技術評論社の解説ページ

ご注文はこちらから


「連載 改訂版 C#入門」のインデックス

連載 改訂版 C#入門

前のページへ 1|2|3|4       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。