反射方法GetFields()的行为是否已更改?

时间:2017-10-13 13:51:47

标签: c# .net reflection .net-4.0 .net-4.5

我的应用程序具有以下代码行,这些代码已经存在很长时间并且一直没有问题。

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

最近我们有一个错误弹出,我追溯到这一行,发现无论出于何种原因,这条特定的线路都没有从反射中返回任何东西。我将该行更新为这样,并恢复了功能。

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

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

更新

好的,所以我重新尝试通过回滚而不是右键单击>来交换回4.0;属性>更改为4.0并且FieldInfo []行再次开始工作。与下面的答案/评论相反,尽管课堂上有属性,但没有对房产进行重构。它们被定义为Jon Hannas在下面的答案中描述的字段。当我启动.net 4.0中的即时窗口并运行GetFields返回预期结果时,GetProperties不返回任何内容。当我在.net 4.5中执行相同操作时,GetProperties返回预期结果,GetFields不返回任何内容。我不知道这是一个错误还是与被定义为部分类的类相关,但GetFields从4.0执行到4.5的方式肯定存在差异或变化。我在框架版本之间查看了关于此方法的C#文档,但没有看到差异。也许以下信息会有所帮助。

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 个答案:

答案 0 :(得分:4)

这两个版本之间没有显着变化。

更重要的是,你拥有的两段代码不是,也绝不是可以互换的。

事实上,您更有可能将使用字段调用的类型更改为使用属性,这是一种常见的重构(特别是因为不建议使用公共字段)。所以你从以下的东西出发:

public class SomeType
{
  public int Something;
  public int SomethingElse;
}

类似

public class SomeType
{
  public int Something { get; set; }
  public int SomethingElse { get; set; }
}

这会使你问题的第一行从返回结果变为不返回任何内容,并使第二行返回的结果与第一行返回的结果相当。

具有讽刺意味的是,引导重构的工具建议使用公共属性而不是字段的原因之一是,您可能必须出于其他原因这样做,这会破坏事情(就像它为您所做的那样)所以最好先从属性开始。一旦它已经被使用,对类型的公共表面进行这样的改变不是一个好主意。