C#学习日记29—-二维索引器 与 foreach遍历索引器

上一篇结尾的时候我留下了几个问题,因为要断电了没有解决,这一篇我们继续上一篇的内容。点这里回到上一篇

问题1:

        数组有多维度的,索引器也可以是多维的吗???

         索引器可以是多维的,上一篇中我们定义的索引器只是一维索引器,同数组一样可以定义多维索引器。比如我们索引电影院的一个放映室的座位号,第一排第一列为1号,一排2列为2号……如下:

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

结果:

662.png

二维的索引器就是如此了,其他多维数的都以此类推,就不介绍了。

 

问题2:

        数组能够使用foreach语句进行简单快捷的遍历,索引器也能使用foreach语句遍历么???

          这个也是可以的,在解决这个问题的时候有必要弄清楚foreach的执行步骤与原理.

foreach语句:

       C#中编译器会把foreach语句转化为IEnumerable接口的方法和属性,比如:

string[] str = new string[] { "HC1", "HC2", "HC3", "HC4" };//定义一个数组              foreach (string i in str)//使用foreach遍历              {                  Console.WriteLine(i);              }

    然而foreach语句会被解析为下面的代码段。  

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

结果都一样:

663.png

我们对string查看定义发现,string继承于IEnumerable接口,IEnumerable接口中只有一个方法GetEnumerator();(该方法已在string类中被实现了)该方法的作用是,返回一个循环访问集合的枚举器IEnumerator,我们在转IEnumerator的定义,它也是一个接口,里面只有三个方法的声明,Current(获取集合中的当前元素),MoveNext(将枚举数推进到集合的下一个元素,成功返回true,越过结尾返回false),Reset( 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前),也就是说,如果在我们自定义的类中没有实现GetEnumerator方法,以及Current、MoveNext方法,就不能使用foreach语句遍历了。

 

foreach语句遍历自定义类:

         还是上面电影院的例子,不过这次我们不用for循环输出,而是实现foreach语句遍历输出,如下:

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

结果:

664.png

 结果是一样的。。。。

以上就是 C#学习日记29—-二维索引器foreach遍历索引器的内容,更多相关内容请关注PHP中文网(www.php.cn)!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1432018.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 06:04:08
下一篇 2025年12月17日 06:05:31

相关推荐

发表回复

登录后才能评论
关注微信