How to find out if a property is an auto-implemented property with reflection?

后端 未结 2 1377
予麋鹿
予麋鹿 2020-11-30 07:40

So in my case i am doing discovery of the structure of a class using reflection. I need to be able to find out if a property is an auto-implemented property by the PropertyI

相关标签:
2条回答
  • 2020-11-30 07:56

    You could check to see if the get or set method is marked with the CompilerGenerated attribute. You could then combine that with looking for a private field that is marked with the CompilerGenerated attribute containing the name of the property and the string "BackingField".

    Perhaps:

    public static bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(
        this PropertyInfo info
    ) {
        bool mightBe = info.GetGetMethod()
                           .GetCustomAttributes(
                               typeof(CompilerGeneratedAttribute),
                               true
                           )
                           .Any();
        if (!mightBe) {
            return false;
        }
    
    
        bool maybe = info.DeclaringType
                         .GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                         .Where(f => f.Name.Contains(info.Name))
                         .Where(f => f.Name.Contains("BackingField"))
                         .Where(
                             f => f.GetCustomAttributes(
                                 typeof(CompilerGeneratedAttribute),
                                 true
                             ).Any()
                         )
                         .Any();
    
            return maybe;
        }
    

    It's not fool proof, quite brittle and probably not portable to, say, Mono.

    0 讨论(0)
  • 2020-11-30 08:02

    This should do:

    public static bool IsAutoProperty(this PropertyInfo prop)
    {
        return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                                 .Any(f => f.Name.Contains("<" + prop.Name + ">"));
    }
    

    The reason is that for auto-properties the Name property of the backing FieldInfo would look like:

    <PropertName>k__BackingField
    

    Since characters < and > wouldn't appear for normal fields, a field with that kind of naming points to a backing field of an auto-property. As Jason says, its brittle still.

    Or to make it a tad faster,

    public static bool IsAutoProperty(this PropertyInfo prop)
    {
        if (!prop.CanWrite || !prop.CanRead)
            return false;
    
        return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                                 .Any(f => f.Name.Contains("<" + prop.Name + ">"));
    }
    
    0 讨论(0)
提交回复
热议问题