配列変数は、一種のインスタンスである。これは、システムに標準で含まれるSystem.Arrayクラスから継承されたものであり、このクラスが公開するメソッドなどはすべて利用可能である。List 15-7はそれを用いた例である。
1: using System;
2:
3: namespace Sample007
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int [] ar = { 0, 1, 2, 3, 4 };
11: for( int i=ar.GetLowerBound(0); i<=ar.GetUpperBound(0); i++ )
12: {
13: Console.WriteLine( ar[i] );
14: }
15: }
16: }
17: }
これを実行するとFig.15-7のようになる。
11行目に出てくるGetLowerBoundメソッドは、配列の添え字の下限の値を返す。GetUpperBoundメソッドは、添え字の上限の値を返す。それぞれ、引数の0というのは、最初の次元を意味する。一次元配列の場合は常にゼロだが、二次元以上になると、何次元目の上限、下限の値を得るか示すために、0から次元数マイナス1の値のいずれかを指定する。このように、配列はただ配列なのではなく、それ自身がインスタンスとしての側面も持つことを忘れてはならない。
すでに述べたとおり、配列はさまざまなメソッドなどを持っている。その中には、IEnumerableというインターフェイスの実装を含む。初心者はIEnumerableの意味を理解する必要はないが、それがもたらす効能については知っておいた方が得である。つまり、foreach文が使えるのである。List 15-8に、それを使った例を示す。
1: using System;
2:
3: namespace Sample008
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int [] ar = { 0, 1, 2, 3, 4 };
11: foreach( int n in ar )
12: {
13: Console.WriteLine( n );
14: }
15: }
16: }
17: }
これを実行するとFig.15-8のようになる。
foreach文の効能により、11行目から14行目までのループを回りながら、配列の要素が1つずつ変数nに代入される。これにより、配列の添え字の範囲を意識することなく、すべての要素にアクセスすることが可能になる。
しかし、foreach文でアクセスした場合、配列の内容を書き換えられないことに注意が必要である。つまり、この場合、変数nの値を書き換えても、それは変数nが変わるだけであって、配列の要素の値が変わることにはならないのである。
System.Arrayクラスには、Sortという名のstaticなメソッドがある。これは、その名のとおり、配列をソートする機能を持ったものである。実際にそれを使った例をList 15-9に示す。
1: using System;
2:
3: namespace Sample009
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int [] ar = { 4, 1, 3, 2, 0 };
11: Array.Sort( ar );
12: foreach( int n in ar )
13: {
14: Console.WriteLine( n );
15: }
16: }
17: }
18: }
これを実行するとFig.15-9のようになる。
見てのとおり、説明を要する箇所はほとんどない。ソートといっても、11行目のSortメソッドの呼び出し一発で終わってしまうのである。
なお前章で紹介したArrayListクラス(System.Collections.ArrayList)にはインスタンスから利用するSortメソッドが存在するが、配列のSortメソッドはstaticである。この違いは頭の片隅に入れておこう。両者の相違をうっかり勘違いすると時間を無駄遣いする恐れがある。
整数のようなシンプルなデータであれば、何も考えないでソートさせるだけで済む。しかし、より複雑な情報を配列変数で扱った場合、いろいろな解釈が可能であるため、そう簡単にソートを実現することはできない。前章では、ArrayListクラス(System.Collections.ArrayList)のソート条件をカスタマイズするサンプルを掲載したが、ここでは配列で条件をカスタマイズする方法を取り上げよう。List 15-10が実際にそれを行ったサンプル・ソースである。
1: using System;
2:
3: namespace Sample010
4: {
5: class Item : IComparable
6: {
7: public string name;
8: public int price;
9: public Item( string name, int price )
10: {
11: this.name = name;
12: this.price = price;
13: }
14: public int CompareTo( object obj )
15: {
16: return price - ((Item)obj).price;
17: }
18: }
19: class Class1
20: {
21: [STAThread]
22: static void Main(string[] args)
23: {
24: Item [] ar =
25: {
26: new Item("チョコ",50),
27: new Item("煎餅",200),
28: new Item("飴",10),
29: new Item("ポテチ",100)
30: };
31: Array.Sort( ar );
32: foreach( Item it in ar )
33: {
34: Console.WriteLine("{0},{1}",it.name,it.price);
35: }
36: }
37: }
38: }
これを実行するとFig.15-10のようになる。
このサンプル・ソースは、Itemクラスの配列をソートする。Itemクラスには名前(name)と価格(price)の2つの情報があり、どちらをソートのキーと見るかによってソート結果が変わってしまう。ここでは、価格でソートしたいとする。ソートが行われる際には、IComparableというインターフェイスを通じて、CompareToというメソッドが呼ばれる。CompareToメソッドの結果をコントロールすることにより、思いどおりの順序でソートさせることが可能になるのである。ComparableインターフェイスとCompareToメソッドの機能は前章で解説したとおりである。
Copyright© Digital Advantage Corp. All Rights Reserved.