Skip to content

Instantly share code, notes, and snippets.

@NickStrupat
Last active March 2, 2023 12:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NickStrupat/39e659e53a7aa000b737 to your computer and use it in GitHub Desktop.
Save NickStrupat/39e659e53a7aa000b737 to your computer and use it in GitHub Desktop.
Get the backing field of an auto-property and vice versa (this only works for auto-props generated by C# compiler, and is not as good as Mono.Reflection.GetBackingField)
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
public static class AutoPropertyExtensions {
const String Prefix = "<";
const String Suffix = ">k__BackingField";
private static String GetBackingFieldName(String propertyName) => $"{Prefix}{propertyName}{Suffix}";
private static String GetAutoPropertyName(String fieldName) {
var match = Regex.Match(fieldName, $"{Prefix}(.+?){Suffix}");
return match.Success ? match.Groups[1].Value : null;
}
public static Boolean IsAnAutoProperty(this PropertyInfo propertyInfo) => propertyInfo.GetBackingField() != null;
public static Boolean IsBackingFieldOfAnAutoProperty(this FieldInfo propertyInfo) => propertyInfo.GetAutoProperty() != null;
public static FieldInfo GetBackingField(this PropertyInfo propertyInfo) {
if (propertyInfo == null)
throw new ArgumentNullException(nameof(propertyInfo));
if (!propertyInfo.CanRead || !propertyInfo.GetGetMethod(nonPublic: true).IsDefined(typeof(CompilerGeneratedAttribute), inherit: true))
return null;
var backingFieldName = GetBackingFieldName(propertyInfo.Name);
var backingField = propertyInfo.DeclaringType?.GetField(backingFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
if (backingField == null)
return null;
if (!backingField.IsDefined(typeof(CompilerGeneratedAttribute), inherit: true))
return null;
return backingField;
}
public static PropertyInfo GetAutoProperty(this FieldInfo fieldInfo) {
if (fieldInfo == null)
throw new ArgumentNullException(nameof(fieldInfo));
if (!fieldInfo.IsDefined(typeof(CompilerGeneratedAttribute), inherit: true))
return null;
var autoPropertyName = GetAutoPropertyName(fieldInfo.Name);
if (autoPropertyName == null)
return null;
var autoProperty = fieldInfo.DeclaringType?.GetProperty(autoPropertyName);
if (autoProperty == null)
return null;
if (!autoProperty.CanRead || !autoProperty.GetGetMethod(nonPublic: true).IsDefined(typeof(CompilerGeneratedAttribute), inherit: true))
return null;
return autoProperty;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment