Property Proxy
public class Property<T>:IEquatable<Property<T>> where T:new() { private T value; public T Value { get => value; set { if (this.value.Equals(value)) return; Console.WriteLine("equals"); this.value = value; } } public Property(): this(default(T)) //this(Activator.CreateInstance<T>()) { } public Property(T t) { this.value = t; } public static implicit operator Property<T>(T t) { return new Property<T>(t); } public static implicit operator T(Property<T> property) { return property.value; } public bool Equals(Property<T> obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; return EqualityComparer<T>.Default.Equals(value, obj.value); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((Property<T>)obj); } public override int GetHashCode() { return value.GetHashCode(); } public static bool operator ==(Property<T> left, Property<T> right) { return Equals(left, right); } public static bool operator !=(Property<T> left, Property<T> right) { return !Equals(left, right); } } class Creature { //public Property<int> Agility { get; set; } private Property<int> agility = new Property<int>(); public int Agility { get => agility.Value; set => agility.Value = value; } } class Program { static void Main(string[] args) { var c = new Creature(); c.Agility = 10; c.Agility = 10; } }