关于C#:反射方法getFields()的行为是否已更改?

Has the behavior of reflection method GetFields() changed?

我有一个应用程序,它有下面一行代码,已经存在了很长一段时间,并且一直在毫无问题地工作。

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

最近我们弹出了一个bug,我追踪到了这条线,发现不管什么原因,这条线并没有从反射中返回任何东西。我更新了该行,使其看起来像这样,功能也恢复了。

1
PropertyInfo[] fields = GetType().GetProperties( BindingFlags.Instance | BindingFlags.Public )

在一个安全补丁中,这种反射行为的方式是否发生了变化?我也在这个应用程序中从4.0升级到了4.5,我认为这个问题与此有关。我回到了4.0版本,仍然存在这个问题,这就是为什么我想知道补丁是否是根本原因。我意识到这是一个非常狭隘的问题,但我做了一些研究,没有提出任何问题。

更新

好的,所以我重新尝试切换回4.0,方法是执行回滚,而不是右键单击>属性>更改为4.0,然后fieldinfo[]行再次开始工作。与下面的答案/注释相反,虽然类上有属性,但没有对属性进行重构。它们被定义为以下乔恩·汉纳斯回答中描述的字段。当我在.NET 4.0中启动即时窗口并运行getFields时,将返回预期的结果,而getProperties则不返回任何结果。当我在.NET 4.5中执行相同操作时,getproperties返回预期的结果,而getfields则不返回任何结果。我不知道这是一个bug还是与被定义为部分类的类相关,但是在从4.0到4.5执行GetFields的方式上肯定存在差异或变化。我查看了框架版本之间关于这个方法的C文档,但没有看到区别。也许下面的信息会有帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public partial class BaseDataObject
{
    public string[] GetFieldNames()
    {
       // GetFields vs. GetProperties code issue here.
    }
}
public partial class ImportInvoice
{
            public ImportInvoice()
            {
                // values of the fields are set here
            }
}

public partial class ImportInvoice : BaseDataObject
{

    public string AField;
    // more fields in a list below.

}


这两个版本之间的差异并不大。

更重要的是,您拥有的两段代码是不能互换的,而且永远也不能互换的。

实际上,您更可能将调用它的类型从使用字段改为使用属性,这是一种常见的重构(特别是不建议使用公共字段)。所以你从以下方面入手:

1
2
3
4
5
public class SomeType
{
  public int Something;
  public int SomethingElse;
}

像这样的

1
2
3
4
5
public class SomeType
{
  public int Something { get; set; }
  public int SomethingElse { get; set; }
}

这会使问题的第一行从返回结果变为不返回任何结果,并使第二行返回结果与第一行返回的结果具有可比性。

具有讽刺意味的是,指导重构的工具推荐使用公共属性而不是字段的原因之一是,无论如何,您可能出于其他原因而必须这样做,这会破坏事情(就像它对您所做的那样),因此最好从属性开始。一旦一个类型已经在使用中,就对它的公共表面进行这样的更改不是一个好主意。