[C# Study Notes] Arrays and Indexers

Insert image description here


array

Arrays have the following properties:

  • Arrays can be one-dimensional, multidimensional, or interleaved.
  • When you create an array instance, the number of latitudes and the length of each latitude are established. These values ​​cannot be changed during the lifetime of the instance.
  • The default value of numeric array elements is set to 0, while reference elements are set to null.
  • A jagged array is an array of arrays, so its elements are reference types and are initialized to null.
  • Arrays are indexed from zero: an array containing n elements is indexed from 0 to n-1.
  • Array elements can be of any type, including array types.
  • Array types are reference types derived from the abstract base type Array. All arrays implement IList and IEnumerable. You can iterate through an array using the foreach statement. Single-dimensional arrays also implement IList and IEnumerable.

Arrays can be defined statically or implicitly

single dimensional array

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" };

Multidimensional Arrays

Different from defining arrays in other languages, defining multi-dimensional arrays uses [,]one more dimension for each question mark. In C#, [][]it is not a multi-dimensional array defined, but a jagged array, which is an array within an array.

int[,] array = new int[4, 2]; //4 * 3 的二维数组
int[,,] array1 = new int[4, 2, 3]; // 4 * 2 * 3 的三维数组

When explicitly defining a multidimensional array, all must be defined.

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" } };

implicit definition

int[,,] array3D = new int[,,] {
    
     {
    
     {
    
     1, 2, 3 }, {
    
     4, 5, 6 } },
                                 {
    
     {
    
     7, 8, 9 }, {
    
     10, 11, 12 } } };

Can be defined without specifying a level

int[,] array4 = {
    
     {
    
     1, 2 }, {
    
     3, 4 }, {
    
     5, 6 }, {
    
     7, 8 } };

jagged array

A jagged array is called an array within an array, and multiple arrays are often defined inside it.

The following defines a jagged array. The first one []defines three arrays inside. The second one []defines the dimensions of the internal array. There is only one dimension here.

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 };

You can also initialize it when declaring

// 交错数组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 }}
;

You can also declare without new:

// 不使用new声明,定义时也需要数组同维度
int[][] jaggedArray4 =
{
    
    
    new int[] {
    
     1, 3, 5, 7, 9 },
    new int[] {
    
     0, 2, 4, 6 },
    new int[] {
    
     11, 22 }
};

Example of defining a multidimensional array by specifying the number of elements and array dimensions

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} }
};

Indexer

The purpose of using indexers is to access non-public array classes in the class. And you can customize getthe methods and setmethods for accessing the index. Indexers can be defined on classes and interfaces.

The type of the indexer and its parameters must be at least as accessible as the indexer. Indexer values ​​cannot be passed by reference (as ref or out parameters).

Indexer on class

method 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
}

Use an indexer to access elements in the class (generally array elements, usually accessed through index, but it can also be used in other situations where serial numbers are required, such as using serial numbers to access the nth number in an int type, of course Can access enumeration types.).

The above indexer can be =>set using the get and set methods:

class Parent
{
    
    
    string[] s = {
    
     "123", "222" };
    public string this[int index]
    {
    
    
        get => s[index];
        set => s[index] = value;
    }
}

Method 2

In the following example, the index value is used to access the index. The indexer set below is read-only and implements the method of accessing the index number through the index value.

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"]);
}

Use accessors getand setmethods to define the readability and writability of indexers (and other variables).


Indexers in interfaces

// 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;
    }
}

According to the above example, IIndexInterfacean indexer is defined in the interface, but the interface itself does not have an int array. And if the get and set permissions are defined in the interface, the get and set of the indexer must be implemented in the inherited class. Therefore, the read and write permissions of the indexer have been defined in the interface.

IndexerClassInherits this interface and defines the read and write accessors of the indexer in the interface.

When multiple indexers with the same name are inherited, of course they also need to be defined using fully qualified names:

string IIndexInterface.this[int index]
{
    
    
}

Guess you like

Origin blog.csdn.net/milu_ELK/article/details/132121203