我有一节课如下:
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);
}
}
通常这类任务都是通过反射来解决的。反射允许您检查类型(在本例中是学生的实例)并询问其属性和与之相关联的方法。优点是您不需要一个名为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#允许您免费获得所有字段。
或者,您可以定义
public Dictionary<string,Func<Student,string>> fields = {
["name"] = s => s.name
, ["family"] = s => s.family
, ["id"] = s => s.id
};