49、c# 能⽤foreach 遍历访问的对象需满足什么条件?

在 C# 中,要使用 foreach 循环遍历一个对象,该对象必须满足以下条件之一:

1. 实现 IEnumerable 或 IEnumerable 接口

  • 非泛型版本:System.Collections.IEnumerable
csharp 复制代码
public class MyCollection : IEnumerable
{
    private int[] _data = { 1, 2, 3 };

    public IEnumerator GetEnumerator()
    {
        return _data.GetEnumerator();
    }
}
  • 泛型版本:System.Collections.Generic.IEnumerable(推荐)
csharp 复制代码
public class MyCollection<T> : IEnumerable<T>
{
    private List<T> _data = new List<T>();

    public IEnumerator<T> GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() // 显式实现非泛型接口
    {
        return GetEnumerator();
    }
}

2. 提供 GetEnumerator() 方法的公共非泛型实现

  • 如果类没有显式实现 IEnumerable,但提供了返回 IEnumerator 的公共方法,foreach 仍可工作:
csharp 复制代码
public class MyCollection
{
    private int[] _data = { 1, 2, 3 };

    public IEnumerator GetEnumerator()
    {
        return _data.GetEnumerator();
    }
}

3. 使用 yield return 自动生成枚举器

  • 编译器会自动为包含 yield return 的方法生成 IEnumerable 实现:
csharp 复制代码
public class MyCollection
{
    public IEnumerable<int> GetItems()
    {
        yield return 1;
        yield return 2;
    }
}

// 使用时:
foreach (var item in new MyCollection().GetItems()) { ... }

4. 数组或字符串(语言内置支持)

  • 数组和字符串即使未显式实现接口,也能直接用 foreach 遍历(编译器特殊处理):
csharp 复制代码
int[] array = { 1, 2, 3 };
foreach (int num in array) { ... } // 合法

string str = "hello";
foreach (char c in str) { ... }    // 合法

关键点总结

  • 必须:对象需提供 GetEnumerator() 方法(通过接口或显式实现)。
  • 推荐:优先使用泛型接口 IEnumerable 以获得类型安全和性能优势。
  • 例外:数组和字符串是语言内置的特殊类型。

示例:完整泛型实现

csharp 复制代码
using System.Collections.Generic;

public class MyList<T> : IEnumerable<T>
{
    private List<T> _items = new List<T>();

    public void Add(T item) => _items.Add(item);

    public IEnumerator<T> GetEnumerator() => _items.GetEnumerator();

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        => GetEnumerator();
}

// 使用:
var list = new MyList<int>();
list.Add(1);
list.Add(2);
foreach (var item in list) { ... } // 正常遍历

通过满足上述条件,任何自定义对象都可以使用 foreach 遍历。

相关推荐
rit843249932 分钟前
MATLAB基于voronoi生成三维圆柱形
开发语言·人工智能·matlab
liulilittle38 分钟前
C/C++ inline-hook(x86)高级函数内联钩子
c语言·开发语言·汇编·c++·hook·底层·钩子
Amelio_Ming40 分钟前
C++开源项目—2048.cpp
linux·开发语言·c++
chilavert31844 分钟前
技术演进中的开发沉思-28 MFC系列:关于C++
开发语言·c++·mfc
witton1 小时前
C语言使用Protobuf进行网络通信
c语言·开发语言·游戏·c·模块化·protobuf·protobuf-c
黄焖鸡能干四碗1 小时前
系统安全设计方案,软件系统安全设计方案
开发语言·数据库·安全·vue·系统安全
dragoooon341 小时前
C++——string的了解和使用
c语言·开发语言·c++·学习·学习方法
格林威2 小时前
Baumer工业相机堡盟工业相机如何通过DeepOCR模型识别判断数值和字符串的范围和相似度(C#)
开发语言·人工智能·python·数码相机·计算机视觉·c#·视觉检测
sanggou2 小时前
InterSystems IRIS安装部署
开发语言
presenttttt2 小时前
用Python和OpenCV从零搭建一个完整的双目视觉系统(五)
开发语言·python·opencv·计算机视觉