How do I know if a property is an auto-implemented property with reflection?
So in my case I am doing an opening of a class structure using reflection. I need to find out if a property is an auto-implemented property of a PropertyInfo object. I'm guessing the reflection API doesn't expose such functionality because auto-properties are C # dependent, but are there any workarounds for this information?
a source to share
You can check whether the method is marked get
or set
attribute CompilerGenerated
. Then you can combine this with finding a private field that is marked with an attribute CompilerGenerated
containing the property name and string "BackingField"
.
May be:
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;
}
This is no wacky proof, rather fragile and probably not portable, say Mono.
a source to share
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
substitution property FieldInfo
would look like this:
<PropertName>k__BackingField
Since symbols <
and are >
not displayed for normal fields, a field with this type of name points to an auto-property support field. As Jason says, he's still fragile.
Or do it a little 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 + ">"));
}
a source to share