class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Age.Value = 100;
person.BankAccountId.Value = 125;
person.BankAccountId.Value = -50;
Console.WriteLine(person);
Console.ReadLine();
}
}
// Использую данный класс для создания списка шаблонных объектов от различных типов.
public abstract class ExtendedProperty : INotifyPropertyChanged
{
protected string description;
public string Description => description;
// Метод set доступен всем - нарушаем инкапсуляцию, но сейчас меня это не волнует.
public abstract object Value { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
// Объект имитирующий свойство.
// Содержит описание свойства. Производит валидацию, логирование.
// На данный момент только для примитивов.
public class ExtendedProperty<T> : ExtendedProperty where T : struct
{
private T _value;
private readonly bool mutable;
public Func<T, bool> Validator;
public ExtendedProperty(string description, T initialValue, bool mutable = true)
{
this.description = description;
this.mutable = mutable;
_value = initialValue;
}
private void setValue(T value)
{
if (mutable)
{
if (Validator != null)
{
if (!Validator(value))
{
Debug.WriteLine($"Wrong assignment | {description}, Value = {value}");
return;
}
}
if (!(_value.Equals(value)))
{
Debug.WriteLine($"Modified | {description}, {_value} -> {value}");
_value = value;
OnPropertyChanged(nameof(Value));
}
}
else
{
Debug.WriteLine($"Attempt to modify immutable value! | {Description}");
}
}
private T getValue()
{
return _value;
}
public override object Value
{
get { return getValue(); }
set { setValue((T)value); }
}
public void Undo() { /* На данный момент не реализовано. */ }
public void Redo() { /* На данный момент не реализовано. */ }
public override string ToString()
{
return $"\n[{Description} : {Value}]";
}
}
public class Person
{
// Теперь не надо прописывать геттеры, сеттеры с логированием, OnPropertyChanged и прочей
// раздражающей глаза, но необходимой ересью.
// Теперь только лямбду для валидации, и то не во всех случаях.
// Пока класс Person, не может узнает об изменениях (потом доработаю).
// Объект будет представлять из себя совокупность ExtendedProperties (правда, с нарушенной инкапсуляцией).
// Вопрос только в том не обернется ли это адом в последующем?
public ExtendedProperty<int> Age = new ExtendedProperty<int>("Person age", 0)
{
Validator = (age) => ((age >= 0) && (age <= 120))
};
public ExtendedProperty<int> BankAccountId = new ExtendedProperty<int>("Bank Account Id", 0)
{
Validator = (id) => (id >= 0)
};
public override string ToString()
{
return $"{Age}{BankAccountId}";
}
}