C# - 文法など - 配列

クラウディア 
1. 概要
2. 初期化
3. 多次元配列
4. 多次元配列の初期化
5. インデックスを求める
6. 先頭・末尾
7. リサイズ

1. 概要

 「C#」は「C++」と似通っているようで、かなり違いますが、配列は特に違いが大きいような気がします。  配列は、クラスでもなく、「namespace」としては、「System」に所属します。  本ページは、下記のサイトを参考にさせていただきました。
Array.IndexOf メソッド (System)」
「Array.Resize(T[], Int32) メソッド (System)」
「C# - 配列の初期化方法」
「[C#]配列(Array)の要素が何番目かを確認するには?」
「2次元配列いろいろ #初心者

2. 初期化

 「C++」で、やっと覚えた、配列の初期化。

int array[2] = {};
 的な、書き方をしますが・・・。  「C#」で、宣言的には、個数を決めずに、スカラ変数の配列を宣言して、0 以外の値で初期化する際は、どうすりゃええんじゃろ?・・・と。  初期化時に、「=」を使わないあたりが、独特でしょうか?

int [] array = new int[] { 1, 2 };
 値が、1 と 2 の、配列数 2 の int 型配列が作成されます。  クラスの配列を宣言する場合、「new」で個数を決めていても配列の中身は「null」のままになっています。  特に、クラス内部に存在する場合は、コンストラクタで配列の個数分、「new」してやらないと、「null」のものを扱うことになってしまうので注意が必要です。  例示しますと。

namespace hogehoge
{
	[Serializable]
	public class classA
	{
		[Serializable]
		public class classB
		{
			public int 		c = 0;
			public string	d = String.Empty;
		}

		public classB[] b	= new classB[10];

		public classA()															//// コンストラクタ
		{
			for (int i=0; i<this.b.Length; i++)
			{
				this.b[i] = new classB();
			}
		}
	}
}
 15~21行のコンストラクタで、配列の各要素にインスタンスを作成しているわけです。  スカラ変数のように列挙することもできます。

using System;

public class myClass
{
	public int 	  age  = 0;
	public string name = String.Empty;
}

public class Program
{
    static public void Main ()
    {

		myClass [] myArray = new myClass[]
			{
				new myClass { age = 20, name = @"hogehoge" },
				new myClass { age = 20, name = @"fugafuga" },
				new myClass { age = 21, name = @"piyopiyo" },
			};

		foreach (myClass m in myArray)
		{
	        Console.WriteLine(@"age = [" + m.age + @"] name[" + m.name + @"] index[" + Array.IndexOf(myArray, m) + @"]");
		}
    }
}
 上記のソースで、ロードモジュールを作成して、実行すると下記の結果が得られます。

age = [20] name[hogehoge] index[0]
age = [20] name[fugafuga] index[1]
age = [21] name[piyopiyo] index[2]

3. 多次元配列

 多次元配列の書き方は、さらに「C++」と乖離していきます。  「2×3」の配列をとるとき、「C++」では。

int array[2][3];
 と書きますが、同じものを「C#」で表現する場合は。

int[,] array = new int[2,3];
 または。

int[][] array = new int[2][3];
 となります(わたしは、下の書き方の方が好きだな)。  配列の個数を「Length」でとりますが、多次元の場合、これは全ての要素の個数になるようで、それぞれの次元の個数をとるには「GetLength(ネスト)」というメソッドを使用します。  前項の初期化の例で書きますと。

namespace hogehoge
{
	[Serializable]
	public class classA
	{
		[Serializable]
		public class classB
		{
			public int 		c = 0;
			public string	d = String.Empty;
		}

		public classB[,] b	= new classB[2,3];

		public classA()															//// コンストラクタ
		{
			for (int i=0; i<this.b.GetLength(0); i++)
			{
				for (int j=0; j<this.b.GetLength(1); j++)
				{
					this.b[i,j] = new classB();
				}
			}
		}
	}
}
 となります。  面倒なので、多次元配列は、なるべく使わないようにしています。  クラス化して、ネストさせた方が、安心して使えます。

4. 多次元配列の初期化

 「[,]」形式の多次元配列の初期化は。

int[,] no = new int[,]{ { 1, 2 } , { 3, 4 }, { 5, 6 } };
 と、まぁこれは、素直に理解できます。  「[][]」の形式は、ちょっと面倒で。

int[][] no = new int[][]{ new int[]{ 1, 2 } , new int[]{ 2, 3 }, new int[]{ 4, 5 } };
 と、小さい単位の方にも、「new」をつけないと、文法エラーになります。

5. インデックスを求める

 クラスの配列で、配列の要素から、インデックスを調べる方法がないものかと調べてみたら、ありました。

Array.IndexOf(配列, 配列の要素)
 インデックスは、もちろん、「0」はじまりです。  配列が、「null」の場合は、「ArgumentNullException」の例外が発生しますが、それ以外の例外はないようです。  クラスでなくてもいいようで、スカラ変数で、同じ要素がある場合は、最初に見つかったインデックスが返ります。  検索対象の要素が存在しない場合は、「-1」が返ります。

using System;

public class myClass
{
	public int 	  age  = 0;
	public string name = String.Empty;
}

public class Program
{
    static public void Main ()
    {

		myClass [] myArray = new myClass[]
			{
				new myClass { age = 20, name = @"hogehoge" },
				new myClass { age = 20, name = @"fugafuga" },
				new myClass { age = 21, name = @"piyopiyo" },
			};

		foreach (myClass m in myArray)
		{
	        Console.WriteLine(@"age = [" + m.age + @"] name[" + m.name + @"] index[" + Array.IndexOf(myArray, m) + @"]");
		}
    }
}
 てなソースを書いて、ビルド・実行すると、下記の結果が得られます。

age = [20] name[hogehoge] index[0]
age = [20] name[fugafuga] index[1]
age = [21] name[piyopiyo] index[2]

6. 先頭・末尾


using System.Linq;
 を使用することにより、「List」と同様、先頭や末尾の要素を取得できます。

using System;
using System.Linq;

public class Program
{
    static public void Main ()
    {
		int[] array = new int[10];

		for (int i=0; i<array.Length; i++)
		{
			array[i] = i+1;
		}

		Console.WriteLine("array 先頭["+ array.First() +"]");
		Console.WriteLine("array 末尾["+ array.Last() +"]");
	}
}
 てなソースを書いて、ビルド・実行すると、下記の結果が得られます。

array 先頭[1]
array 末尾[10]

7. リサイズ

 「C#」では、配列の個数は、宣言時に変数を使って初期化できるだけでなく、実行時に状況に合わせて、動的にサイズを変えることが可能です。

Array.Resize (ref T[] array, int newSize);
 で、第一引数に、配列のリファレンスを渡し、第二引数に個数を設定することで、サイズを変えられます。
earthcar(アースカー)
それがだいじWi-Fi