Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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?

like image 442
Zoki Avatar asked Feb 05 '10 20:02

Zoki


People also ask

Which one is an auto implemented property?

Auto-implemented properties declare a private instance backing field, and interfaces may not declare instance fields. Declaring a property in an interface without defining a body declares a property with accessors that must be implemented by each type that implements that interface.

What is an automatic property?

What is automatic property? Automatic property in C# is a property that has backing field generated by compiler. It saves developers from writing primitive getters and setters that just return value of backing field or assign to it. Instead of writing property like this: public class Dummy.


2 Answers

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.

like image 115
jason Avatar answered Sep 20 '22 08:09

jason


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 + ">")); } 
like image 41
nawfal Avatar answered Sep 21 '22 08:09

nawfal