- Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
ReadOnlyPropertiesClass readOnlyPropertiesClass = new ReadOnlyPropertiesClass();
ReflectionHelper.SetReadOnlyPropertyValue(readOnlyPropertiesClass, "PropertyWithUnderscore", "PropertyWithUnderscoreValue");
ReflectionHelper.SetReadOnlyPropertyValue(readOnlyPropertiesClass, "PropertyWithMUnderscore", "PropertyWithMUnderscoreValue");
Console.WriteLine(readOnlyPropertiesClass.PropertyWithUnderscore);
Console.WriteLine(readOnlyPropertiesClass.PropertyWithMUnderscore);
}
}
public class ReadOnlyPropertiesClass
{
private string _PropertyWithUnderscore = "";
private string m_PropertyWithMUnderscore = "";
public string PropertyWithUnderscore { get { return _PropertyWithUnderscore; } }
public readonly string PropertyWithMUnderscore { get { return m_PropertyWithMUnderscore; } }
}
public static class ReflectionHelper
{
public static bool SetReadOnlyPropertyValue(object target, string propertyName, object newValue)
{
if (target == null)
throw new ArgumentNullException(nameof(target));
if (propertyName == null)
throw new ArgumentNullException(nameof(propertyName));
Type type = target.GetType();
PropertyInfo prop = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (prop == null)
throw new ArgumentException($"Property '{propertyName}' not found on type '{type.FullName}'.");
// Only look for _PropertyName and m_PropertyName
string[] backingFieldNames = new[]
{
$"_{propertyName}",
$"m_{propertyName}"
};
FieldInfo backingField = null;
foreach (var fieldName in backingFieldNames)
{
backingField = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
if (backingField != null)
break;
}
if (backingField == null)
{
throw new Exception ($"Backing field for property '{propertyName}' not found.");
return false;
}
backingField.SetValue(target, newValue);
return true;
}
}
}



