我的代码中有一个结构,如下所示
public struct ColumnSpec
{
public string specName;
public string delimiters;
public string commentChars;
public int titleLines;
public Column[] Columns;
public SymbolFile testrangefile;
public ColumnSpec(bool input)
{
specName = null;
delimiters = null;
commentChars = null;
titleLines = 0;
Columns = new Column[3];
Columns[0] = new Column();
Columns[1] = new Column();
Columns[2] = new Column();
testrangefile = new SymbolFile();
}
}
现在我有了这个结构的实例 ColumnSpec计算;
当我在下面的循环中使用它时,我收到一个错误,说ColumnSpec不包含'GetEnumerator'的定义
foreach (string element in computed)
{
}
你可以帮助解决错误。
答案 0 :(得分:1)
对于有枚举器的东西,它需要实现你的结构不是
的IEnumerable
答案 1 :(得分:1)
C#中的调查员不会按照您的想法执行操作。它们习惯于显式或隐式地遍历项目集合,如数组,列表或实现IEnumerable
接口的其他对象。它们不习惯迭代结构的字段。
有两种方法可以做你想做的事。第一种方法是覆盖ToString
结构中的ColumnSpec
方法。 ToString()
是.NET中所有类型共享的标准方法,并为您的类型提供打印输出逻辑。由于它是在代码中实现的,因此您可以显式引用字段并从中创建单个字符串。
如果您正在寻找通用解决方案,那么您将不得不研究Reflection,它允许您在运行时检查结构的字段和属性,并且具有与您的结构类似的语法。我试过了:
ColumnSpec computed; // your instance.
Type myType = typeof(ColumnSpec); The reflected Type of ColumnSpec.
string combinedString = "";
foreach (FieldInfo field in myType.GetFields()) // this enumerates all public fields.
{
if (field.FieldType == typeof(string)) // only for strings
{
string fieldValue = field.GetValue(computed); // extract the value.
combinedString += fieldValue;
}
}
这是一个简化的示例,但它应该让您开始使用Reflection。更全面的解决方案将让您使用反射深入深入到Column
对象数组中,并从中提取数据。
@Corak的评论中提到的第三个选项将允许您将值作为枚举器公开,维护它们的顺序,但没有反射,只需在结构中添加以下方法:
public IEnumerable<string> GetElements()
{
yield return specName;
yield return delimiters;
. . . // you get the idea.
foreach (Column column in Columns)
{
yield return column.Name;
}
yield return testrangefile.Filename;
}
这将公开IEnumerable字符串,而显式yield
ing允许您按照您想要的顺序懒惰地填充此可枚举。然后你可以这样称呼它:
foreach (string element in computed.GetElements())
{
}
答案 2 :(得分:0)
我认为你不需要一个枚举器。通过向ToString()
ColumnSpec
,您可以获得所需内容
public override string ToString()
{
return String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}",
specName,
delimiters,
Columns[0],
Columns[1],
Columns[2],
testrangefile.fname,
testrangefile.sname);
}