我正在尝试使用反射来清理我的班级。
private List<String> centers = new List<String>();
private List<String> leftWingers = new List<String>();
private List<String> rightWingers = new List<String>();
private List<String> defencemen = new List<String>();
private List<String> goalies = new List<String>();
private List<String> bench = new List<String>();
public List<String> Centers { get { return centers; } set { centers = value; } }
public List<String> LeftWingers { get { return leftWingers; } set { leftWingers = value; } }
public List<String> RightWingers { get { return rightWingers; } set { rightWingers = value; } }
public List<String> Defencemen { get { return defencemen; } set { defencemen = value; } }
public List<String> Goalies { get { return goalies; } set { goalies = value; } }
public List<String> Bench { get { return bench; } set { bench = value; } }
public String ToString()
{
String output = "";
System.Reflection.PropertyInfo[] properties = this.GetType().GetProperties();
foreach (System.Reflection.PropertyInfo property in properties)
{
int count = 0;
foreach (String value in property)
{
count++;
output += "C" + count + ": " + value + System.Environment.NewLine;
}
}
}
这不起作用。我似乎无法循环每个属性的项目,因为它们是集合。有没有办法从PropertyInfo对象中获取字符串列表的内容?
答案 0 :(得分:3)
GetFields
您需要告诉GetFields
方法您想获得private
会员使用BindingFlags
,否则默认会查找public
和instance
成员。
var fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
答案 1 :(得分:1)
好吧,如果你真的想要属性,首先是你的代码没有属性。你只有一些属性。对于样本:
,如果是这种情况,请更改属性private List<String> centers { get; set; }
private List<String> leftWingers { get; set; }
private List<String> rightWingers { get; set; }
private List<String> defencemen { get; set; }
private List<String> goalies { get; set; }
private List<String> bench { get; set; }
然后你可以将它们作为集合和读取值读取,样本:
public String ToString()
{
StringBuilder output = new StringBuilder();
System.Reflection.PropertyInfo[] properties = this.GetType().GetProperties();
foreach (System.Reflection.PropertyInfo property in properties)
{
var values = property.GetValue(this, null) as IEnumerable<String>;
if (values != null)
{
int count = 0;
foreach (String value in values)
{
count++;
output.AppendLine(string.Format("C{0}: {1}", count, value));
}
}
}
return output.ToString();
}
另一种情况是读取字段并避免将其转换为属性。看看Selman22的回答!
答案 2 :(得分:1)
使用Enumerable.Concat
,Enumerable.Select
和string.Join
可以大大简化您的问题:
IEnumerable<string> allItems = centers.Concat(leftWingers)
.Concat(rightWingers)
.Concat(defencemen)
.Concat(goalies)
.Concat(bench);
return string.Join
(
Environment.NewLine,
allItems.Select((item, index) => $"C {index + 1}: {item}")
);
答案 3 :(得分:0)
这些是字段,因此您需要使用GetFields
来获取它们。请注意,反射返回的字段只是元数据,它们不包含您需要的数据。
要获取数据,您需要使用GetValue
方法获取当前对象的字段值。
然后,为了能够在字段中枚举集合,您需要将其转换为IEnumerable<string>
。
以下是它的样子:
public String ToString()
{
String output = "";
var fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var field in fields)
{
int count = 0;
foreach (String value in (IEnumerable<string>) field.GetValue(this))
{
count++;
output += "C" + count + ": " + value + System.Environment.NewLine;
}
}
return output;
}
由于您只有6个集合,因此您可以拥有不涉及反射的解决方案。这是一个例子:
public String ToString()
{
String output = "";
var collections = new[] {centers, leftWingers, rightWingers, defencemen, goalies, bench};
foreach (var field in collections)
{
int count = 0;
foreach (String value in field)
{
count++;
output += "C" + count + ": " + value + System.Environment.NewLine;
}
}
return output;
}
请考虑使用StringBuilder
代替string
。使用string
连接字符串会损害性能。