【问题标题】:C# Reflection - Get field values from a simple classC# Reflection - 从一个简单的类中获取字段值
【发布时间】:2011-11-30 17:59:20
【问题描述】:

我有一堂课:

class A {
    public string a = "A-val" , b = "B-val";
}

我想通过反射打印对象成员

//Object here is necessary.
Object data = new A();
FieldInfo[] fields = data.GetType().GetFields();
String str = "";
foreach(FieldInfo f in fields){
    str += f.Name + " = " + f.GetValue(data) + "\r\n";
}

这是想要的结果:

a = A-val
b = B-val

不幸的是,这不起作用。请帮忙,谢谢。

【问题讨论】:

  • 为什么不顺利?出了什么问题?
  • 您的代码(稍作修改以使其编译)确实可以工作......到底有什么问题?
  • 我没有尝试编译这个但是 f.GetValue(data) 没有返回一个对象?这应该是 .ToString() 放入字符串中
  • @Martin Booth:GetValue 返回一个对象,但你可以将一个对象添加到字符串中,这样就可以(或多或少)

标签: c# reflection


【解决方案1】:

一旦修复以消除错误(缺少分号和错误的变量名),您发布的代码确实工作 - 我刚刚尝试过,它显示名称和值没有问题。

我的猜测是,实际上,您正在尝试使用不公开的字段。这段代码:

FieldInfo[] fields = data.GetType().GetFields();

... 只会获得 public 字段。您通常需要指定您还需要非公共字段:

FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public | 
                                              BindingFlags.NonPublic | 
                                              BindingFlags.Instance);

(我希望你没有真的有公共领域,毕竟......)

【讨论】:

  • 这些字段不是公开的吗?
  • @MartinBooth:是的,我正在编辑 - 基本上它实际上可以使用给定的代码,但我怀疑当它不起作用时,OP 有私有字段。
  • 我不知道您必须明确指定BindingFlags.Instance - 我认为这是默认设置。但是,如果没有该标志,在我的情况下没有返回任何字段。
  • @Oliver:如果您指定 any 标志,则需要指定它。默认值类似于“公共、实例、静态”。
  • @JonSkeet 截至今天 8/18/2015 我得到的默认值是:BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
【解决方案2】:

记住当你写字段时:

public string VarName{ get; set;}

那么实际上你有这个代码(这是反射看到的):

private string _varName;
public string get_VarName(){
....
}
public void set_VarName(strig value){
....
}

【讨论】:

  • 不想在旧帖子上吹毛求疵(3 年旧帖子上的线程坏死),但public string VarName { get; set; } 根本不是一个字段。这是一个财产。具体来说,就像您编写的那样,在编译时创建一个私有字段的自动属性。但财产本身只是财产。如果有人碰巧遇到这个并感到困惑,只是想弄清楚这一点。
【解决方案3】:

正如@Stanislav 所说,您必须牢记编译器为属性生成的支持字段。如果要排除这些字段,可以使用以下代码:

FieldInfo[] fields = data.GetType()
    .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
    .Where(f => f.GetCustomAttribute<CompilerGeneratedAttribute>() == null)
    .ToArray();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多