简体   繁体   English

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

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

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.我需要能够确定某个属性是否是 PropertyInfo 对象自动实现的属性。 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?我假设反射 API 不会公开此类功能,因为自动属性依赖于 C#,但是否有任何解决方法来获取此信息?

You could check to see if the get or set method is marked with the CompilerGenerated attribute.您可以检查getset方法是否标有CompilerGenerated属性。 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" .然后,您可以将其与查找标记为CompilerGenerated属性的私有字段相结合,该属性包含属性名称和字符串"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.它不是万无一失的,非常脆弱,可能无法移植到 Mono 等。

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:原因是对于自动属性,支持FieldInfoName属性如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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