Home > Article > Backend Development > C# Learning Diary 29----Two-dimensional indexer and foreach traversal indexer
At the end of the previous article, I left a few questions, which were not solved because the power was about to be cut off. In this article, we will continue the content of the previous article. Click here to return to the previous article
Question 1:
Arrays have multiple dimensions, can indexers also be multi-dimensional? ? ?
Indexers can be multi-dimensional. The indexer we defined in the previous article is only a one-dimensional indexer. Like an array, a multi-dimensional indexer can be defined. For example, if we index the seat number of a screening room in a cinema, the first column in the first row is No. 1, and the second column in the first row is No. 2... as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test1 {//定义cinema类包含一个二维数组与一个二维访问器 class cinema {//定义一个二维数组 private string[,] seat = new string[5, 5]; //定义一个二维访问器 public string this[uint a, uint b] { get { return seat[a, b]; } set { seat[a, b] = value; } } } class Program { static void Main(string[] args) { cinema movieroom = new cinema();//实例化 //for循环遍历写入 for (uint i = 1; i < 5; i++) { for (uint j = 1; j < 5; j++) { movieroom[i, j] = "第" + i + "排 第" + j + "列"; } } //for循环遍历读出 for (uint i = 1; i < 5; i++) { for (uint j = 1; j < 5; j++) { Console.WriteLine(movieroom[i,j]+"\t"+((i-1)*4+j)+"号"); } } } } }
Result:
This is the case for two-dimensional indexers. Other multi-dimensional indexers are similar and will not be introduced.
Question 2:
The array can be traversed simply and quickly using the foreach statement. Can the indexer also be traversed using the foreach statement? ? ?
This is also possible. When solving this problem, it is necessary to clarify the execution steps and principles of foreach.
foreach statement:
The compiler in C# will The statement is converted into the methods and properties of the IEnumerable interface, such as:
string[] str = new string[] { "HC1", "HC2", "HC3", "HC4" };//定义一个数组 foreach (string i in str)//使用foreach遍历 { Console.WriteLine(i); }
However, the foreach statement will be parsed into the following code segment.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; //注意添加这个命名空间,否则没有IEnumerator这个类 namespace Example { class Program { static void Main(string[] args) { string[] str = new string[] {"HC1","HC2","HC3","HC4" }; //定义一个数组 //调用GetEnumerator()方法,获得数组的一个枚举 IEnumerator per = str.GetEnumerator(); //在while循环中,只要MoveNext()返回true,就一直循环下去 while (per.MoveNext()) { //用Current属性访问数组中的元素 string p = (string)per.Current; Console.WriteLine(p); } } } }
The results are the same:
We looked at the definition of string and found that string inherits from the IEnumerable interface, and the IEnumerable interface There is only one method GetEnumerator(); (this method has been implemented in the string class). The function of this method is to return an enumerator IEnumerator that iterates through the collection. We are changing the definition of IEnumerator, which is also an interface. There are only three method declarations, Current (get the current element in the collection), MoveNext (advance the enumerator to the next element of the collection, return true if successful, return false if it exceeds the end), Reset (set the enumerator to it The initial position, which is before the first element in the collection), that is to say, if the GetEnumerator method, as well as the Current and MoveNext methods are not implemented in our custom class, we cannot use the foreach statement to traverse.
foreach statement traverses custom classes:
It’s still the movie theater example above, but this time we don’t use a for loop to output, but implement a foreach statement to traverse the output, as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; //添加这个很有必要 namespace Test1 {//定义cinema继承IEnumerable接口实现GetEnumerator()功能 class cinema:IEnumerable {//定义一个二维数组 private string[,] seat = new string[5, 5]; //定义座位号码 static public int index=-1; //定义一个二维索引器 public string this[uint a, uint b] { get { return seat[a, b]; } set { seat[a, b] = value; }//set访问器自带value参数 } //实现GetEnumerator方法 public IEnumerator GetEnumerator() { return new ienumerator(seat); //利用构造方法传入seat参数 } //由于上面返回值的需要所以继承接口IEnumerator并实现方法 private class ienumerator:IEnumerator { private string[,] seats; //将传入的seat数组赋给它 public ienumerator(string[,] s) { seats = s; } //定义Current的只读属性 public object Current { //根据座位号推算数组的坐标也就是物理位置 get { return seats[1+(index/4), (index%4)+1]; } } //定义向下移动的规则 public bool MoveNext() { index++; //索引下一个座位号的位置 if (index <= 15) { return true; } else return false; } //因为这个程序中用不到这个方法所以不实现,但是必须得写上否则会报错 public void Reset() { } } } class Program { static void Main(string[] args) { cinema movieroom = new cinema();//实例化 //for循环索引写入 for (uint i = 1; i < 5; i++) { for (uint j = 1; j < 5; j++) { movieroom[i, j] = "第" + i + "排 第" + j + "列"; } } //调用foreach语句遍历输出 foreach (string i in movieroom) { Console.WriteLine(i+"\t"+(cinema.index+1)+"号"); } } } }
Result:
The result is the same. . . .
The above is the content of C# Learning Diary 29----two-dimensional indexer and foreach traversal indexer. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!