LSTANCZYK
9/25/2017 - 1:35 AM

gistfile1.cs

class ObservableDataPropertyAttribute : Attribute
{
}

class DependsOnAttribute : Attribute
{
    public string Dependency { get; private set; }

    public DependsOnAttribute(string dependency)
    {
        Dependency = dependency;
    }
}

class ValidationAttribute : Attribute
{
}

abstract class ObservableType : IDisposable
{
    //When Dispose is called, all Observables are terminated (and send the OnCompleted signal to the Observers)
    public abstract void Dispose();

    //The OnNext event is only triggered *once* when multiple properties are changed.
        //If two properties of different types should be listened to, then their base common type should be used (e.g. System.Object)
    public IObservable<T> GetObservableForProperties<T>(params string[] propertyNames)
    {
        //TODO
        return null;
    }

    protected static T New<T>() where T : ObservableType
    {
        //TODO: Implement this.
        return null;
    }
}

abstract class Person : ObservableType
{
    [ObservableDataProperty]
    public abstract string FullName { get; set; }

    [DependsOn("FullName")]
    public char FirstNameLetter {
        get { return FullName[0]; }
    }

    [ObservableDataProperty]
    public virtual int Age
    {
        get;
        [Validation]
        set
        {
            if (value <= 0)
                throw new ArgumentOutOfRangeException("age");
        }
    }

    public static Person New(string fullName)
    {
        var person = ObservableType.New<Person>();
        person.FullName = fullName;
        return person;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var person = Person.New("Default Name");
        using (var personNameListener = person.GetObservableForProperties<string>("FullName").Subscribe(newName =>
        {
            //It is also possible to listen to FirstNameLetter. The events are sent at the same time, since FirstNameLetter depends on FullName.
            Console.WriteLine("New Name {0}", newName);
        }))
        {
            person.FullName = "Some New Value";
        }
    }
}