配列
配列には次のプロパティがあります。
- 配列は、1 次元、多次元、またはインターリーブにすることができます。
- 配列インスタンスを作成すると、緯度の数と各緯度の長さが設定されます。これらの値は、インスタンスの存続期間中は変更できません。
- 数値配列要素のデフォルト値は 0 に設定され、参照要素は null に設定されます。
- ギザギザ配列は配列の配列であるため、その要素は参照型であり、null に初期化されます。
- 配列には 0 からインデックスが付けられます。n 個の要素を含む配列には 0 から n-1 までのインデックスが付けられます。
- 配列要素は、配列型を含む任意の型にすることができます。
- 配列型は、抽象基本型 Array から派生した参照型です。すべての配列は IList と IEnumerable を実装します。foreach ステートメントを使用して配列を反復処理できます。1 次元配列も IList と IEnumerable を実装します。
配列は静的または暗黙的に定義できます
一次元配列
int[] array = new int[5];
int[] array1 = new int[] {
1, 3, 5, 7, 9 }; // 定长为5,不是动态的
int[] array2 = {
1, 3, 5, 7, 9 }; // 定长
string[] weekDays2 = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
多次元配列
他の言語での配列の定義とは異なり、多次元配列の定義では[,]
疑問符ごとに 1 つ多くの次元を使用します。C# では、[][]
多次元配列が定義されるのではなく、配列内の配列であるギザギザ配列が定義されます。
int[,] array = new int[4, 2]; //4 * 3 的二维数组
int[,,] array1 = new int[4, 2, 3]; // 4 * 2 * 3 的三维数组
多次元配列を明示的に定義する場合は、すべてを定義する必要があります。
int[,] array2Da = new int[4, 2] {
{
1, 2 }, {
3, 4 }, {
5, 6 }, {
7, 8 } };
string[,] array2Db = new string[3, 2] {
{
"one", "two" }, {
"three", "four" },
{
"five", "six" } };
暗黙の定義
int[,,] array3D = new int[,,] {
{
{
1, 2, 3 }, {
4, 5, 6 } },
{
{
7, 8, 9 }, {
10, 11, 12 } } };
レベルを指定せずに定義可能
int[,] array4 = {
{
1, 2 }, {
3, 4 }, {
5, 6 }, {
7, 8 } };
ギザギザの配列
ギザギザの配列は配列内配列と呼ばれ、配列内に複数の配列が定義されることがよくあります。
以下はギザギザ配列を定義します。最初の配列は[]
内部の 3 つの配列を定義します。2 番目の配列は[]
内部配列の次元を定義します。ここには次元が 1 つだけあります。
int[][] jaggedArray = new int[3][];
// 初始化,数组只需维度相同,元素数不定
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];
// 上述定义和下面语句相同
jaggedArray[0] = new int[] {
1, 3, 5, 7, 9 };
jaggedArray[1] = new int[] {
0, 2, 4, 6 };
jaggedArray[2] = new int[] {
11, 22 };
宣言時に初期化することもできます
// 交错数组new声明的第一个[]不定义数量
// 但是new声明的第二个[]必须定义维度数量
int[][] jaggedArray2 = new int[][]
{
new int[] {
1, 3, 5, 7, 9 },
new int[] {
0, 2, 4, 6 },
new int[] {
11, 22 }
};
// 定义的二维交错数组
int[][,] jaggedArray3 = new int[][,]
{
new int[,] {
{
1,2 }, {
3,3 }}
;
new なしで宣言することもできます。
// 不使用new声明,定义时也需要数组同维度
int[][] jaggedArray4 =
{
new int[] {
1, 3, 5, 7, 9 },
new int[] {
0, 2, 4, 6 },
new int[] {
11, 22 }
};
要素数と配列の次元を指定して多次元配列を定義する例
int[][,] jaggedArray5 = new int[3][,]
{
new int[,] {
{
1,3}, {
5,7} },
new int[,] {
{
0,2}, {
4,6}, {
8,10} },
new int[,] {
{
11,22}, {
99,88}, {
0,9} }
};
インデクサ
インデクサーを使用する目的は、クラス内の非パブリック配列クラスにアクセスすることです。また、インデックスにアクセスするためのget
メソッドやメソッドをカスタマイズできます。set
インデクサーはクラスとインターフェイスで定義できます。
インデクサーのタイプとそのパラメーターは、少なくともインデクサーと同じくらいアクセス可能である必要があります。インデクサー値は、参照によって (ref または out パラメーターとして) 渡すことはできません。
クラスのインデクサ
方法1
class Parent
{
string[] s = {
"123", "222" };
public string this[int index]
{
get
{
return s[index];
}
set
{
s[index] = value;
}
}
}
void Start()
{
Parent p = new Parent();
Debug.Log(p[1]); // 222
p[1] = "555"; // 输入值默认value
Debug.Log(p[1]); // 555
}
インデクサーを使用して、クラス内の要素 (通常はインデックスを介してアクセスされる配列要素) にアクセスしますが、シリアル番号を使用して int 型の n 番目の数値にアクセスするなど、シリアル番号が必要な他の状況でも使用できます。もちろん列挙型にアクセスできます。)。
上記のインデクサーは、=>
get メソッドと set メソッドを使用して設定できます。
class Parent
{
string[] s = {
"123", "222" };
public string this[int index]
{
get => s[index];
set => s[index] = value;
}
}
方法 2
次の例では、インデックス値を使用してインデックスにアクセスします。以下のインデクサー セットは読み取り専用で、インデックス値を通じてインデックス番号にアクセスするメソッドを実装します。
class DayCollection
{
string[] days = {
"Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };
public int this[string day] => FindDayIndex(day);
private int FindDayIndex(string day)
{
for (int j = 0; j < days.Length; j++)
{
if (days[j] == day)
{
return j;
}
}
throw new ArgumentOutOfRangeException(
nameof(day),
$"Day {
day} is not supported.\nDay input must be in the form \"Sun\", \"Mon\", etc");
}
}
void Start()
{
DayCollection Days = new DayCollection();
Debug.Log(Days["Sat"]);
}
アクセサーget
とset
メソッドを使用して、インデクサー (およびその他の変数) の読み取り可能性と書き込み可能性を定義します。
インターフェースのインデクサー
// Indexer on an interface:
public interface IIndexInterface
{
// Indexer declaration:
int this[int index]
{
get;
set;
}
}
// Implementing the interface.
class IndexerClass : IIndexInterface
{
private int[] arr = new int[100];
public int this[int index] // indexer declaration
{
// The arr object will throw IndexOutOfRange exception.
get => arr[index];
set => arr[index] = value;
}
}
上記の例によれば、IIndexInterface
インデクサーはインターフェイス内で定義されていますが、インターフェイス自体には int 配列がありません。また、get および set 権限がインターフェイスで定義されている場合は、インデクサーの get および set を継承クラスに実装する必要があります。したがって、インデクサーの読み取りおよび書き込み権限はインターフェイスで定義されています。
IndexerClass
このインターフェイスを継承し、インターフェイス内のインデクサーの読み取りおよび書き込みアクセサーを定義します。
同じ名前を持つ複数のインデクサーが継承される場合、もちろん、それらも完全修飾名を使用して定義する必要があります。
string IIndexInterface.this[int index]
{
}