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

心已入冬 提交于 2019-11-26 11:14:49

问题


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 PropertyInfo object. I assume that the reflection API does not expose such functionality because auto-properties are C# dependent, but is there any workaround to get this information?


回答1:


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.




回答2:


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 + ">"));
}


来源:https://stackoverflow.com/questions/2210309/how-to-find-out-if-a-property-is-an-auto-implemented-property-with-reflection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!