【问题标题】:An example for supporting foreach without implementing IEnumerable在不实现 IEnumerable 的情况下支持 foreach 的示例
【发布时间】:2014-01-31 17:31:03
【问题描述】:

我正在查看this blog ,它解释了foreach 可以在不实现IEnumerable 的情况下得到支持。但没有深入到实现的细节。

我正在寻找如何在不实现 IEnumerable 的情况下支持 foreach 的示例。

编辑:感谢@Sam 我的评论,我得到了我想要的东西。 (见下面我的回答)

【问题讨论】:

  • 这篇文章看起来很清楚。你不明白什么?
  • 首先,编写一个实现IEnumerable的类,然后去掉说你正在实现IEnumerable和viola的那一行!你明白了

标签: c# foreach ienumerable


【解决方案1】:

这是一个没有实现 IEnumerable 或任何接口的类:

public class Foo 
{
    public IEnumerator<int> GetEnumerator()
    {
        yield return 1;
        yield return 2;
    }
}

你可以像这样foreach它:

foreach (int n in new Foo())
    Console.WriteLine(n);

这将打印:

1
2

【讨论】:

  • +1。实际上,您也可以手动实现IEnumerator 的方法,并且不是从IEnumerator 派生 ...但是示例会更长。 foreach 是 C# 中 duck-typing(以及新的 dynamic)的示例。
  • @AlexeiLevenkov 是的,我这样做只是因为它比这样的解决方案要短得多,因为这意味着我不能使用迭代器块。
【解决方案2】:

感谢@Sam 我的评论,我能够调整this page 上的代码并将以下内容放在一起,而无需使用 IEnumerable 或 IEnumerator:

   //Person Object
   public class Person
   {
        public Person(string fName, string lName)
        {
            this.firstName = fName;
            this.lastName = lName;
        }
    string firstName;
    public string lastName;
   }

   //****Object Collection. 
   //****This class usually needs to implement IEnumerable 
   //****But we are avoiding that here.
   public class People
   {
      private Person[] _people;
      public People(Person[] pArray)
        {
           _people = new Person[pArray.Length];    
           for (int i = 0; i < pArray.Length; i++)
           {
              _people[i] = pArray[i];
           }
         }

    public PeopleEnumSimulator GetEnumerator()
    {
        return new PeopleEnumSimulator(_people);
    }

    public class PeopleEnumSimulator
    {
        public Person[] _people;

        int position = -1;

        public PeopleEnumSimulator(Person[] list)
        {
            _people = list;
        }

        public bool MoveNext()
        {
            position++;
            return (position < _people.Length);
        }

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

        public Person Current
        {
            get
            {
                try
                {
                    return _people[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
}   


//****Now, Use the Foreach
    Person[] myPeople = new Person[3]
    {
        new Person("John", "Smith"),
        new Person("Jim", "Johnson"),
        new Person("Sue", "Rabon"),
    };
    People peopleList = new People(myPeople);
    foreach (Person p in peopleList)
        Response.Write(p.firstName + " " + p.lastName);





//****************************************
//******** A Generic Implementation********
public class People<T>
{
    private T[] _people;
    public People(T[] pArray)
    {
        _people = new T[pArray.Length];

        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }

    public PeopleEnumSimulator GetEnumerator()
    {
        return new PeopleEnumSimulator(_people);
    }

    public class PeopleEnumSimulator
    {
        public T[] _people;

        int position = -1;

        public PeopleEnumSimulator(T[] list)
        {
            _people = list;
        }

        public bool MoveNext()
        {
            position++;
            return (position < _people.Length);
        }

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

        public T Current
        {
            get
            {
                try
                {
                    return _people[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
}

       // use the foreach
       //For Type Person
            People<Person> peopleList = new People<Person>(myPeople);

            foreach (Person p in peopleList)
                Response.Write(p.firstName + " " + p.lastName);

            //break
            Response.Write(" </br></br></br>       ");

            //For Type Int
            int[] n3 = { 2, 4, 6, 8 };

            People<int> intList = new People<int>(n3);

            foreach (int p in intList)
                Response.Write(p);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2013-02-01
    • 1970-01-01
    • 2020-01-14
    • 2016-09-30
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多