Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
354 views
in Technique[技术] by (71.8m points)

c# - Using Reflection to determine which Fields are backing fields of a Property

I'm using reflection to map out objects. These objects are in managed code but I have no visibility into their source code, underlying structure, etc. other than through reflection. The overarching goal of all this is a rudimentary memory map of an object (similar in functionality to SOS.dll DumpObject and !ObjSize commands). As such, I'm trying to determine which members are being "double counted" as both a field and a property.

For example:

public class CalendarEntry
{
    // private property 
    private DateTime date { get; set;}

    // public field 
    public string day = "DAY";
}

When mapped shows:

  • Fields
    • day
    • k__BackingField
  • Properties
    • date

Where as a class like this:

public class CalendarEntry
{
    // private field 
    private DateTime date;

    // public field 
    public string day = "DAY";

    // Public property exposes date field safely. 
    public DateTime Date
    {
        get
        {
            return date;
        }
        set
        {
                date = value;
        }
    }
}

When mapped shows:

  • Fields
    • day
    • date
  • Properties
    • Date

At first glance there's nothing to tell you that the Date property's "backing field" is the field named date. I'm trying to avoid counting date twice in this scenario since that will give me a bad memory size approximation.

What's more confusing/complicated is I've come across scenarios where properties don't always have a corresponding field that will be listed through the Type.GetFields() method so I can't just ignore all properties completely.

Any ideas on how to determine if a field in the collection returned from Type.GetFields() is essentially the backing field of some corresponding property returned from Type.GetProperties()?

Edit- I've had trouble determining what conditions a property will not have a corresponding field in listed in the collection returned from Type.GetFields(). Is anyone familiar with such conditions?

Edit 2- I found a good example of when a property's backing field would not be included in the collection returned from Type.GetFields(). When looking under the hood of a String you have the following:

  • Object contains Property named FirstChar
  • Object contains Property named Chars
  • Object contains Property named Length
  • Object contains Field named m_stringLength
  • Object contains Field named m_firstChar
  • Object contains Field named Empty
  • Object contains Field named TrimHead
  • Object contains Field named TrimTail
  • Object contains Field named TrimBoth
  • Object contains Field named charPtrAlignConst
  • Object contains Field named alignConst

The m_firstChar and m_stringLength are the backing fields of the Properties FirstChar and Length but the actual contents of the string are held in the Chars property. This is an indexed property that can be indexed to return all the chars in the String but I can't find a corresponding field that holds the characters of a string. Any thoughts on why that is? Or how to get the backing field of the indexed property?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The name of a property's backing field is a compiler implementation detail and can always change in the future, even if you figure out the pattern.

I think you've already hit on the answer to your question: ignore all properties.

Remember that a property is just one or two functions in disguise. A property will only have a compiler generated backing field when specifically requested by the source code. For example, in C#:

public string Foo { get; set; }

But the creator of a class need not use compiler generated properties like this. For example, a property might get a constant value, multiple properties might get/set different portions of a bit field, and so on. In these cases, you wouldn't expect to see a single backing field for each property. It's fine to ignore these properties. Your code won't miss any actual data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...