提问者:小点点

C#:如何循环通过类中的数组定义的成员


我有一节课如下:

    class Student 
    {
        private string name;
        private string family;
        private string id;

        public string[] fields = {"name", "family", "id"};

        public Student(string name,string family,string id)
        {
            this.name = name;
            this.family = family;
            this.id = id;
        }              
    }

现在,在另一个类中,我希望循环遍历数组中定义的成员。这是我的代码不工作

    class StudentController
    {
        Student student;

        public StudentController(Student st)
        {
            this.student = st;

        }
        public void store()
        {
             foreach(string f in this.student.fields)
                    Console.WriteLine(this.student.f);
        }
    }

共2个答案

匿名用户

通常这类任务都是通过反射来解决的。反射允许您检查类型(在本例中是学生的实例)并询问其属性和与之相关联的方法。优点是您不需要一个名为field的字符串数组,并且如果添加新成员,遍历属性的代码不会改变。缺点是使用反射会对性能产生相对的影响(但真正关心的是,您应该始终在您的真实环境中进行测试)

但是您也可以实现一个简单的替代方法,创建您自己版本的ToString方法。

例如,将学生类扩展为

public class Student
{
    private string name;
    private string family;
    private string id;

    public string[] fields = { "name", "family", "id", "all" };

    public Student(string name, string family, string id)
    {
        this.name = name;
        this.family = family;
        this.id = id;
    }
    public string ToString(string field)
    {
        switch (field)
        {
            case "name":
                return this.name;
            case "family":
                return this.family;
            case "id":
                return this.id;
            case "all":
            default:
                return $"{name}, {family}, {id}";
        }
    }
}

现在您可以用

Student t = new Student("John", "McEnroe", "134");
foreach(string s in t.fields)
    Console.WriteLine(t.ToString(s));

匿名用户

字段名不是字段值的替身,因此引用了对象中不存在的名为的字段或属性,从而导致了该错误。

有多种方法可以解决这个问题,这取决于你的口味。例如,您可以使用反射来获取Field的值(链接中的答案是关于属性的;您可以调整它来使用Field,或者切换到properties,这是一种更粗俗的方式)。一个额外的好处是,您不再需要定义所有字段的列表,除非您想要,因为C#允许您免费获得所有字段。

或者,您可以定义/code>的集合,其中函子访问特定字段:

public Dictionary<string,Func<Student,string>> fields = {
    ["name"] = s => s.name
,   ["family"] = s => s.family
,   ["id"] = s => s.id
};