using System.Linq.Expressions;
public static void Main()
user.TrySetValue(c => c.UserName, "User name");
user.TrySetValue(c => c.Password, "Password");
user.TrySetValue(c => c.IsReadOnly, false);
user.TrySetValue(c => c.UserName, "some other value");
user.TrySetValue(c => c.Password, "some other password");
public interface IReadOnlyAbility
public class User : IReadOnlyAbility {
public bool IsReadOnly {get; private set;}
public string UserName { get; private set; }
public string Password { get; private set; }
public void MakeReadonly() => IsReadOnly = true;
public override string ToString()
=> $"UserName:{UserName}, Password: {Password}, IsReadonly: {IsReadOnly}";
public static class IReadOnlyAbilityExtensions
public static bool TrySetValue<T, TValue>(this T target, Expression<Func<T, TValue>> memberLambda, TValue value)
where T : IReadOnlyAbility
if(target.IsReadOnly) return false;
if (memberLambda.Body is MemberExpression memberSelectorExpression
&& memberSelectorExpression.Member is PropertyInfo property
&& property.Name != nameof(target.IsReadOnly))
property.SetValue(target, value, null);