提问人:junkforce 提问时间:10/26/2008 最后编辑:Robert Harveyjunkforce 更新时间:9/7/2018 访问量:31679
如何在 C# 中找到对象的所有公共字段?
How can I find all the public fields of an object in C#?
问:
我正在构造一种方法来接受 ArrayList(大概是满满的对象),然后列出 ArrayList 中每个对象的所有字段(及其值)。
目前我的代码如下:
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
string field = type.GetFields().ToString();
Console.WriteLine(field);
}
}
当然,我理解这段代码的直接问题:如果它有效,它只会在 ArrayList 中为每个对象打印一个字段。我稍后会解决这个问题 - 现在我只是好奇如何获取与对象关联的所有公共字段。
答:
35赞
Dave Markle
10/26/2008
#1
foreach (Object obj in list) {
Type type = obj.GetType();
foreach (var f in type.GetFields().Where(f => f.IsPublic)) {
Console.WriteLine(
String.Format("Name: {0} Value: {1}", f.Name, f.GetValue(obj));
}
}
请注意,此代码需要 .NET 3.5 才能工作 ;-)
评论
0赞
junkforce
10/26/2008
没关系。我更喜欢这种技术。我也可以推断它来获取属性(甚至方法)。谢谢一堆!
1赞
Goodies
1/5/2018
谢谢 .where 条件 Dave..我知道这是 10 年后,但我喜欢它。简单。。只有公众..不需要 Getsetters..不用担心,它仍然可以在 VS 2017 .net 4.6.2 和核心:p中与 c# 一起使用
0赞
GreySage
9/14/2021
请注意该类型。GetFields() 始终只获取公共字段,因此不需要过滤公共字段。
4赞
nyxtom
10/26/2008
#2
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
Console.WriteLine("{0} -- ", type.Name);
Console.WriteLine(" Properties: ");
foreach (PropertyInfo prop in type.GetProperties())
{
Console.WriteLine("\t{0} {1} = {2}", prop.PropertyType.Name,
prop.Name, prop.GetValue(obj, null));
}
Console.WriteLine(" Fields: ");
foreach (FieldInfo field in type.GetFields())
{
Console.WriteLine("\t{0} {1} = {2}", field.FieldType.Name,
field.Name, field.GetValue(obj));
}
}
}
我想提一下,在字段中查找 IsPublic 不是必需的类型。MSDN 定义的 GetFields() 指出:
返回值 - 类型:System.Reflection.FieldInfo[]
一个 FieldInfo 对象数组,表示为当前 Type 定义的所有公共字段。
1赞
Jon B
10/26/2008
#3
static void ListArrayListMembers(ArrayList list)
{
foreach (object obj in list)
{
Type type = obj.GetType();
foreach (FieldInfo field in type.GetFields(BindingFlags.Public))
{
Console.WriteLine(field.Name + " = " + field.GetValue(obj).ToString());
}
}
}
10赞
Jonathan Webb
10/26/2008
#4
您可以使用 BindingFlags 获取直接在类中声明的所有对象字段:
GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
以及所有对象字段,包括继承的:
GetFields(BindingFlags.Public | BindingFlags.Instance)
5赞
Marc Gravell
10/26/2008
#5
当然,另一个问题是“你为什么有公共领域?”——属性是可取的。作为抽象,请注意,反射并不是唯一的选择:类型也可以在运行时动态公开其属性(例如非类型化/将列公开为属性的方式)。DataTable
DataView
为了支持这一点(同时也支持简单对象),您可以使用:TypeDescriptor
foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
这也允许许多扩展性选项 - 例如,大大加快反射速度(无需更改任何代码)。
评论
0赞
Nyerguds
12/19/2013
美。这允许我为一个抽象超类创建一个通用的 ToString(),该超类显示其大多数子类包含的两个属性(“Key”和“Code” - 是一个数据库对象类),而不需要有关所述子类的任何特定信息:)
评论