微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 使用反射生成迭代器

我有一个数据类学生,我有一个聚合类学生.
Student有两个类型为string的属性:Name和City.

我想要做的是选择使用foreach机制选择要迭代的属性.

我写的代码有效,它也可读,外观漂亮.
主要问题是性能:我使用yield关键字的行可能不是很有效,但问题是多少?这是戏剧性的表现吗?

有没有更好的方法来实现此功能
(补充:我不想让某人修改返回的Student对象,因此所提出的所有Linq解决方案都不是很好.为了更清楚,我希望:
属性迭代foreach机制集成学生类和学生列表是只读的.
我怎么能实现这一目标?)

static void Main(string[] args)
    {           
        Students students = new Students();

        students.AddStudent(new Student { Age = 20,Name = "Stud1",City="City1" });
        students.AddStudent(new Student { Age = 46,Name = "Stud2",City="City2"});
        students.AddStudent(new Student { Age = 32,Name = "Stud3",City="City3" });
        students.AddStudent(new Student { Age = 34,Name = "Stud4",City="city4" });

        students.PropertyToIterate = eStudentProperty.City;
        foreach (string studentCity in students)
        {
            Console.WriteLine(studentcity);
        }

        students.PropertyToIterate = eStudentProperty.Name;
        foreach (string studentName in students)
        {
            Console.WriteLine(studentName);
        }

    }

public class Students :IEnumerable<object>
{
    private List<Student> m_Students = new List<Student>();

    private eStudentProperty m_PropertyToIterate = eStudentProperty.Name;

    public eStudentProperty PropertyToIterate
    {
        get { return m_PropertyToIterate; }
        set { m_PropertyToIterate = value; }
    }

    public void AddStudent(Student i_Student)
    {
        m_Students.Add(i_Student);
    }

    public IEnumerator<object> GetEnumerator()
    {            
        for (int i = 0; i < m_Students.Count; ++i)
        {
            yield return (object)m_Students[i].GetType().GetProperty(PropertyToIterate.ToString()).GetValue(m_Students[i],null);
        }            
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

public enum eStudentProperty
{
    Name,Age,City
} 

public class Student
{
    public string Name { get; set; }

    public string City { get; set; }

    public int Age { get; set; }
}

解决方法

为了回应你的编辑,这样的事情怎么样……

Students students = new Students();
students.AddStudent(new Student { Age = 20,City = "City1" });
students.AddStudent(new Student { Age = 46,City = "City2" });
students.AddStudent(new Student { Age = 32,City = "City3" });
students.AddStudent(new Student { Age = 34,City = "city4" });

foreach (int studentAge in students.EnumerateBy(StudentProperty.Age))
{
    Console.WriteLine(studentAge);
}

foreach (string studentName in students.EnumerateBy(StudentProperty.Name))
{
    Console.WriteLine(studentName);
}

foreach (string studentCity in students.EnumerateBy(StudentProperty.City))
{
    Console.WriteLine(studentCity);
}

// ...

public class Students
{
    private List<Student> _students = new List<Student>();

    public void AddStudent(Student student)
    {
        _students.Add(student);
    }

    public IEnumerable<T> EnumerateBy<T>(StudentProperty<T> property)
    {
        return _students.Select(property.Selector);
    }
}

public static class StudentProperty
{
    public static readonly StudentProperty<int> Age =
        new StudentProperty<int>(s => s.Age);

    public static readonly StudentProperty<string> Name =
        new StudentProperty<string>(s => s.Name);

    public static readonly StudentProperty<string> City =
        new StudentProperty<string>(s => s.City);
}

public sealed class StudentProperty<T>
{
    internal Func<Student,T> Selector { get; private set; }

    internal StudentProperty(Func<Student,T> selector)
    {
        Selector = selector;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐