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;
}              
}

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

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);
}
}

字段名称不是字段值的替代,因此this.student.f引用了Student对象中不存在的名为f的字段或属性,从而导致错误。

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

或者,您可以定义Func<Student,string>的集合,其中函数访问特定字段:

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

现在,您可以在fields上进行迭代,并在进行时打印名称和值:

foreach(string p in student.fields)
Console.WriteLine("{0} = {1}", p.Key, p.Value(student));

通常使用反射来解决这类任务。反射api系统允许您检查Type(在本例中是Student的实例(,并询问其属性和与之相关的方法。其优点是,您不需要字符串的公共字段数组,如果添加新成员,遍历属性的代码也不会更改。缺点是使用反射会对性能产生相对影响(但要真正担心的是,您应该始终在真实环境中进行测试(

但是,您也可以实现一个简单的替代方案,创建自己版本的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));

或者仅针对具有的单个字段

Console.WriteLine(t.ToString("name"));

如果您试图访问中的值

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

然后改一下:

foreach(string f in this.student.fields)
Console.WriteLine(this.student.f);

对此:

foreach(string f in this.student.fields)
Console.WriteLine(f);

您试图访问变量f,就像它是StudentController的成员一样。

但是,如果您试图访问传递给Student构造函数的namefamilyid的值,请将这些字段转换为以下属性:

public string Name { get; set; }
public string Family { get; set; }
public string Id { get; set; }

并使用以下代码访问它们:

foreach(var property in typeof(Student).GetProperties()) {
var propValue = property.GetValue(student);
Console.WriteLine(propValue);
}

如果您只从Student类设置这些属性,那么您可以这样做:

public string Name { get; }

或者这个:

public string Name { get; private set; }

相关内容

  • 没有找到相关文章