能用foreach遍历访问的对象需要实现____接口或声明____方法的类型

本文详细介绍了如何使自定义类支持Foreach遍历,包括实现IEnumerable接口、重写GetEnumerator方法以及创建自定义IEnumerator类的三种方法。通过具体示例,展示了Item和ItemList类的设计与遍历过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前面试看到一个这样的笔试题,当时只知道List和Dictionary类型可以用foreach遍历,但他两也没什么共同点啊。List是有序的,但Dictionary是无序的。回来在网上查了下才发现,他们都实现了IEnumerable接口,申明了GetEnumerator方法。打开源码后发现确实如此:

接下来就详细写一下自定义的类如果用foreach遍历。

首先定义一个Item类

public class Item
{
    public int Id;
    public string Name;
    public int Price;

    public Item(int id, string name, int price)
    {
        Id = id;
        Name = name;
        Price = price;
    }
}

接下来要写的类就是暴漏给外部调用,实现了IEnumerable的ItemList.

public class ItemList : IEnumerable
{
    private Item[] items;

    public int Count
    {
        get { return items.Length; }
    }

    public ItemList(Item[] _items)
    {
        items = _items;
    }
    public Item this[int index]
    {
        get { return items[index]; }
    }
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < items.Length; i++)
        {
            yield return items[i];
        }
    }
    //public IEnumerator GetEnumerator()
    //{
    //    return items.GetEnumerator();
    //}
}

这里可以不实现IEnumerable接口,但是GetEnumerator方法必须申明,不然在调用时会报错。而GetEnumerator方法,这里写了前两种方法。一种是通过for循环依次返回,一种是因为[]本身就实现了IEnumerable,所有可以直接用它的GetEnumerator。

然后写一个测试代码:

ItemList itemList=new ItemList(new Item[]{new Item(1,"apple",3),new Item(2,"banana",3)  });
        foreach (Item item in itemList)
        {
            Debug.Log(item.Id+"__"+item.Name+"__"+item.Price);
        }

这样就可以通过foreach遍历自己写的ItemList类了。

还有第三种方法,就是自己重写一个实现IEnumerator的类

public class ItemListEnumerator : IEnumerator
{
    private int index = -1;
    private ItemList itemList;

    public ItemListEnumerator(ItemList _itemList)
    {
        itemList = _itemList;
    }

    public object Current
    {
        get { return itemList[index]; }
    }

    public bool MoveNext()
    {
        index++;
        return index < itemList.Count;
    }

    public void Reset()
    {
        index = -1;
    }
}

然后修改ItemList中的GetEnumerator方法

  public IEnumerator GetEnumerator()
    {
       return new ItemListEnumerator(this);
    }

至此让一个自定义类可以被foreach遍历的三种方法都有了。而写到这里,对IEnumerator做一些猜想。因为在写协程时,返回的参数同样是IEnumerator类型。而这里相当于每调用一次,就像Next实现的一样,把指针指向了下一个元素。再深究,感觉就是IEnumerator自身到底是一个什么类型的东西了,起什么作用。

最后附上两个链接,我这篇相当于对这两位笔者博文的结合。

https://blog.youkuaiyun.com/qq_39081464/article/details/81023878

https://blog.youkuaiyun.com/zfq18317916225/article/details/50717751

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值