如何确定属性是否是具有反射的自动实现的属性?

Zok*_*oki 27 .net c# reflection automatic-properties

所以在我的情况下,我正在使用反射来发现类的结构.我需要能够通过PropertyInfo对象找出属性是否是自动实现的属性.我假设反射API没有公开这样的功能,因为自动属性是C#依赖的,但是有没有解决方法来获取这些信息?

jas*_*son 24

您可以检查getset方法是否标有CompilerGenerated属性.然后,您可以将其与查找标记有CompilerGenerated包含属性名称和字符串的属性的私有字段组合在一起"BackingField".

也许:

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;
    }
Run Code Online (Sandbox Code Playgroud)

它不是万无一失,非常脆弱,可能不适用于Mono.


naw*_*fal 14

这应该做:

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

原因是对于自动Name属性,支持的属性FieldInfo如下所示:

<PropertName>k__BackingField
Run Code Online (Sandbox Code Playgroud)

由于人物<>将不会出现在正常领域,具有那种命名点自动属性支持字段的字段.正如杰森所说,它仍然脆弱.

或者让它更快一点,

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 + ">"));
}
Run Code Online (Sandbox Code Playgroud)