遍历结构体成员

23

假设我们有一个结构体:

Struct myStruct
{
   int var1;
   int var2;
   string var3;
   .
   .
}

是否可以通过foreach循环遍历结构体的成员变量呢?我已经阅读了一些关于反射的内容,但是不确定如何在这里应用。

结构体中有大约20个变量。我正在尝试从文件中读取值,并尝试将它们分配给变量,但不想调用20次file.ReadLine()。我正在尝试通过循环访问成员变量。


3
@kr13:你几乎肯定不应该有一个包含20个字段的结构体。请参阅http://msdn.microsoft.com/en-us/library/ms229017.aspx。 - Jon Skeet
将您的结构体转换为数组或列表,并/或使用序列化库。 - H H
可能是遍历结构体?的重复问题。 - user7116
@JonSkeet:16字节大小限制非常脆弱,并且在处理未经管理的API或DTO时经常被忽略。但是,对于许多其他原因,OP可能不应该使用结构体。 - H H
1
@HenkHolterman:是的,我并不太在意大小限制,但这几乎肯定不“逻辑上表示单个值,类似于基本类型”。 - Jon Skeet
1个回答

49

您可以与正常情况下一样使用Type.GetFields来应用反射:

MyStruct structValue = new MyStruct(...);

foreach (var field in typeof(MyStruct).GetFields(BindingFlags.Instance |
                                                 BindingFlags.NonPublic |
                                                 BindingFlags.Public))
{
     Console.WriteLine("{0} = {1}", field.Name, field.GetValue(structValue));
}

请注意,如果该结构体公开了属性(几乎肯定会这样),您可以使用Type.GetProperties获取这些属性。

(正如评论中所指出的那样,在第一次尝试这样做时可能并不是一个好主意,“总的来说”,我对用户定义的结构体持怀疑态度,但我还是想包含实际答案……)

编辑:现在似乎您对“设置”字段感兴趣,由于值类型的工作方式(是的,这个结构体真的不应该存在),这会稍微复杂一些。您需要进行装箱(box)操作,然后对单个装箱实例上的值进行设置,最后再取消装箱(unbox):

object boxed = new MyStruct();

// Call FieldInfo.SetValue(boxed, newValue) etc

MyStruct unboxed = (MyStruct) boxed;

谢谢你的回答!但似乎我可能让事情变得不必要地复杂了。我会看看是否可以使用列表来实现同样的事情。 - kr13
请注意,如果结构体公开属性(几乎肯定应该这样做),您可以使用Type.GetProperties来获取这些属性。我可以问一下为什么结构体应该公开属性?为什么不是简单的变量? - Naresh
@Naresh:因为字段应该是存储关注点,而不是公共API的一部分 - 至少在几乎所有情况下都是如此。 (有例外情况。)请参见http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx - Jon Skeet
非常感谢 @JonSkeet.. 我也收到了你的新书.. 我会在书中寻找更多细节.. - Naresh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接