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?
Asked
Active
Viewed 6,213 times
2 Answers
26
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.

jason
- 236,483
- 35
- 423
- 525
-
Thanks a lot Jason, the Reflector told me the same in the meantime:) Should have thought of it earlier. – Zoki Feb 05 '10 at 21:02
-
1@3o4eTo: Just be forewarned that this not fool proof, brittle and possibly not portable to Mono. – jason Feb 05 '10 at 21:07
-
Also take care of the exception when there is no getter on the property. – nawfal May 12 '13 at 11:22
-
True. Why do we need to check for the attribute? – vexe Dec 26 '13 at 11:54
-
In addition to the other restrictions, this will only work for auto-props generated by C#. VB.NET compiler uses the pattern of just putting prefixing `_` to the auto-prop name, but does include the `CompilerGeneratedAttribute` attribute. The F# compiler does not use apply that attribute and uses yet another naming convention. – Nick Strupat Jan 24 '16 at 23:44
-
@NickStrupat could you please give some hints if these compiler inconsistencies are still the same now in 2017? I can't find any detailed documentation about these. – Zoltán Tamási Jan 28 '17 at 10:33
15
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 + ">"));
}

nawfal
- 70,104
- 56
- 326
- 368