C#中迭代器实现的一点问题

C#中迭代器实现的一点问题

问题的提出

在C# 入门经典(第七版)这本书中,Chapter11的课后习题中遇到的问题。

要求:创建一个集合类People ,它是下述Person类的集合,该集合中的项可以通过一个字符串索引符来访问,该字符串索引符是人的姓名,与Person.Name 属性相同:

(2) 扩展上一题中的Person 类,重载>、<、>=和<=运算符,比较Person实例的Age属性。

(3) 给People 类添加GetOldest()方法,使用上面定义的重载运算符,返回其Age属性值为最大的Person 对象数组(1个或多个对象,因为对于这个属性而言,多个项可以有相同的值)。

(4) 在People 类上执行ICloneable接口,提供深度复制功能。

(5) 给People 类添加一个迭代器,在下面的foreach循环中获取所有成员的年龄:

foreach(int age in myPeople.Ages)
{
//Display ages.
}

问题的初始解答

 //person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ch11Excise
{
    public class Person
    {
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }


        private string name;
        private int age;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public static bool operator >(Person person1,Person person2)
        {
            return (person1.age > person2.age);
        }

        public static bool operator <=(Person person1,Person person2)
        {
            return !(person1 > person2);
        }

        public static bool operator <(Person person1,Person person2)
        {
            return (person1.age < person2.age);
        }

        public static bool operator >=(Person person1,Person person2)
        {
            return !(person1 < person2);
        }
    }
}


//people.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace Ch11Excise
{
    public class People:DictionaryBase,ICloneable,IEnumerable
    {
        public void Add(Person newPerson)
        {
           Dictionary.Add(newPerson.Name,newPerson.Age);
        }

        public void Remove(string nameId)
        {
            Dictionary.Remove(nameId);
        }

        public People() { }

        public Person this[string nameID]
        {
            get { return (Person)Dictionary[nameID]; }
            set { Dictionary[nameID] = value; }
        }

        public IEnumerable Persons
        {
            get
            {
                foreach (object person in Dictionary.Values)
                {
                    yield return (person as Person);
                }
            }
        }

        public IEnumerable Ages
        {
            get
            {
                foreach(object person in Dictionary.Values)
                {
                    yield return (person as Person).Age;
                }
            }
        }

        public People GetOldest()
        {
            Person personOldest=null;
            People peopleOldest = new People() ;
            Person currentPerson;

            foreach(DictionaryEntry p in Dictionary)
            {
                currentPerson = p.Value as Person;
                if(personOldest==null)
                {
                    personOldest = currentPerson;
                    peopleOldest.Add(currentPerson);
                }
                else
                {
                    if (currentPerson>personOldest)
                    {
                        peopleOldest.Clear();
                        peopleOldest.Add(currentPerson);
                        personOldest = currentPerson;
                    }
                    else
                    {
                        if(currentPerson>=personOldest)
                        {
                            peopleOldest.Add(currentPerson);
                        }

                    }
                }
            }

            return peopleOldest;
        }

        public object Clone()
        {
            People clonedPeople = new People();
            foreach(Person person in Dictionary)
            {
                clonedPeople.Add(person);
            }
            return clonedPeople;
        }
    }
}



//Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
using System.Collections;
namespace Ch11Excise
{
    class Program
    {
        static void Main(string[] args)
        {
            People people1 = new People();
            Person person1 = new Person("lan", 24);
            Person person2 = new Person("xiu", 23);
            Person person3 = new Person("wen", 27);

            people1.Add(person1);
            people1.Add(person2);
            people1.Add(person3);

            WriteLine("the person in people is :");
            foreach(Person person in people1.Persons)
            {
                WriteLine($"{person.Name}");
            }

            foreach(int age in people1.Ages)
            {
                WriteLine($"{age}");
            }
            ReadKey();
        }
    }
}

问题出现

问题出现

问题分析

反正就是找了很多办法问题都没得到解决,后来想来古人所云:请寻其本,重新分析基础定义的代码。发现问题

问题解决

是由于在对People类实现的DictionaryBase里的Add实现上出现了问题

public void Add(Person newPerson)
{
    Dictionary.Add(newPerson.Name,newPerson.Age);
}

这里的Add参数出现了问题,Add函数的定义为

void Add(object key, object value);

所以改为

public void Add(Person newPerson)
{
    Dictionary.Add(newPerson.Name,newPerson);//之前用的newPerson.Age就完全错误了
}

至此,问题解决

测试程序输出

问题解决