简体   繁体   中英

Has the behavior of reflection method GetFields() changed?

I have an application that has the following line of code that's been there for quite some time and has been working without issue.

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

Recently we had a bug pop up that I traced back to this line and found that for whatever reason this particular line wasn't returning anything from reflection. I updated the line to look like this and functionality was restored.

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

Has something changed in a security patch where the way this reflection behaves would have been altered? I also upgraded from 4.0 to 4.5 in this app and thought the issue was related to that. I rolled back to 4.0 and still had the issue which is why I'm wondering if a patch might be the root cause. I realize this is a very narrow question but I did some research and didn't come up with anything.

Update

Ok so I re-tried swapping back to 4.0 by doing a rollback instead of a right click > properties > change to 4.0 and the FieldInfo[] line started working again. Contrary to the answers/comments below there was not a refactoring to properties though there were properties on the class. They are defined as fields as described in Jon Hannas answer below. When I fire up the immediate window in .net 4.0 and run the GetFields returns expected results and GetProperties returns nothing. When I do the same in .net 4.5 GetProperties returns the expected results and GetFields returns nothing. I don't know if this is a bug or related to the class being defined as a partial class but there is definitely a difference or change in the way GetFields is executed from 4.0 to 4.5. I looked through the C# documentation on this method between framework versions and didn't see a difference though. Maybe the information below will help.

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.

}

Those haven't changed significantly between those two versions.

What's more, the two pieces of code you have are not, and never were, interchangeable.

It seems more likely that you in fact changed the type it is called on from using fields to using properties, which is a common refactoring (especially since public fields aren't recommended). So you went from something like:

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

To something like

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

That would have made the first line in your question change from returning results to returning nothing, and make the second line return results comparable to those the first used to return.

Ironically, one of the reasons why having public properties instead of fields is recommended by tools guiding refactorings is the fact that you might have to do so for some other reason anyway, and that would break things (as it did for you) so it's better to start out with properties in the first place. It's not a good idea to do such a change to the public surface of a type once it is already in use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM