Net.Like.Xue.Tokyo/Assets/BITKit/Core/Wrapper/IWrapper.cs

135 lines
3.4 KiB
C#

using System;
using System.Reflection;
namespace BITKit
{
public interface IWrapper
{
public object Obj { get; set; }
}
public interface IWrapper<T>:IWrapper
{
public Action<T, T> OnValueChanged { get; set; }
public T Value { get; set; }
}
public class ValueWrapper<T> : IWrapper<T>
{
public ValueWrapper()
{
var type = typeof(T);
if (type == typeof(string))
{
_value = string.Empty.As<T>();
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<T>();
}
}
public Action<T, T> 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<T> : IWrapper<T>
{
private readonly PropertyInfo _field;
private readonly object _target;
public Action<T, T> 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<T> : IWrapper<T>
{
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<T, T> 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<T> : IWrapper<T>
{
private readonly Func<T> _get;
private readonly Action<T> _set;
public FuncWrapper(Func<T> get, Action<T> set)
{
_get = get;
_set = set;
}
public Action<T, T> OnValueChanged { get; set; }
public T Value
{
get => _get();
set => _set(value);
}
public object Obj
{
get => Value;
set => Value = (T)value;
}
}
}