using System; using System.Reflection; namespace BITKit { public interface IWrapper { public object Obj { get; set; } } public interface IWrapper:IWrapper { public Action OnValueChanged { get; set; } public T Value { get; set; } } public class ValueWrapper : IWrapper { public ValueWrapper() { var type = typeof(T); if (type == typeof(string)) { _value = string.Empty.As(); return; } if(type.IsAbstract || type.IsInterface)return; // 检查类型是否具有公共无参数构造函数 var constructor = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); if (constructor is not null) { _value = Activator.CreateInstance(); } } public Action OnValueChanged { get; set; } public T Value { get => _value; set { var prev = _value; _value = value; OnValueChanged?.Invoke(prev,value); } } private T _value; public object Obj { get => Value; set => Value = (T)value; } } public class PropertyWrapper : IWrapper { private readonly PropertyInfo _field; private readonly object _target; public Action OnValueChanged { get; set; } public PropertyWrapper(PropertyInfo field, object target) { _field = field; _target = target ?? throw new ArgumentNullException(nameof(target)); } public T Value { get => (T)_field.GetValue(_target); set { var prev = Value; _field.SetValue(_target, value); OnValueChanged?.Invoke(prev, value); } } public object Obj { get => Value; set => Value = (T)value; } } public class FieldWrapper : IWrapper { private readonly FieldInfo _field; private readonly object _target; public FieldWrapper(FieldInfo field, object target) { _field = field; _target = target ?? throw new ArgumentNullException(nameof(target)); } public Action OnValueChanged { get; set; } public T Value { get => (T)_field.GetValue(_target); set { OnValueChanged?.Invoke(Value, value); _field.SetValue(_target, value); } } public object Obj { get => Value; set => Value = (T)value; } } public class FuncWrapper : IWrapper { private readonly Func _get; private readonly Action _set; public FuncWrapper(Func get, Action set) { _get = get; _set = set; } public Action OnValueChanged { get; set; } public T Value { get => _get(); set => _set(value); } public object Obj { get => Value; set => Value = (T)value; } } }