{"action":"created","issue":{"url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/11","labels_url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/11/labels{/name}","comments_url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/11/comments","events_url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/11/events","html_url":"https://github.com/runceel/ReactiveProperty/issues/11","id":115387531,"number":11,"title":"ReactiveProperty should inherit from ReadOnlyReactiveProperty","user":{"login":"JohnBillington","id":7782048,"avatar_url":"https://avatars.githubusercontent.com/u/7782048?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnBillington","html_url":"https://github.com/JohnBillington","followers_url":"https://api.github.com/users/JohnBillington/followers","following_url":"https://api.github.com/users/JohnBillington/following{/other_user}","gists_url":"https://api.github.com/users/JohnBillington/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnBillington/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnBillington/subscriptions","organizations_url":"https://api.github.com/users/JohnBillington/orgs","repos_url":"https://api.github.com/users/JohnBillington/repos","events_url":"https://api.github.com/users/JohnBillington/events{/privacy}","received_events_url":"https://api.github.com/users/JohnBillington/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-11-05T22:14:28Z","updated_at":"2015-11-10T13:16:44Z","closed_at":null,"body":"It would be useful if the `ReactiveProperty` class inherited from the `ReadOnlyReactiveProperty` class. That way, we can have a private ReactiveProperty and a public ReadOnlyReactiveProperty with the same object as their value. This effectively lets us have private setters and public getters, but with a reactive property.\r\n\r\n# Example\r\n\r\n    // In this class we have an IsDirty boolean value that can change. We want\r\n    // it to be possible to change it from inside the class,\r\n    // but impossible to change it from outside the class except by actually\r\n    // changing one of the other properties.\r\n\r\n    public class MountainViewModel\r\n    {\r\n        private ReactiveProperty<bool> _isDirty = new ReactiveProperty<bool>();\r\n\r\n        // This is cleaner than having a line initializing\r\n        // IsDirty in the constructor\r\n        public ReadOnlyReactiveProperty<bool> IsDirty => _isDirty;\r\n\r\n        public ReactiveProperty<string> Name { get; } = new ReactiveProperty<string>();\r\n\r\n        public ReactiveProperty<double> HeightInMeters { get; } = new ReactiveProperty<double>();\r\n\r\n        public MountainViewModel()\r\n        {\r\n            Name.Subscribe(_ => _isDirty.Value = true);\r\n            HeightInMeters.Subscribe(_ => _isDirty.Value = true);\r\n        }\r\n    }\r\n\r\n    // Example usage of MountainViewModel:\r\n\r\n    var mvm = new MountainViewModel();\r\n\r\n    // This line causes a compile error because IsDirty is a\r\n    // ReadOnlyReactiveProperty. This is good! We don't want people\r\n    // to manually set the dirty bit.\r\n    mvm.IsDirty.Value = true;\r\n\r\n    // The only way to change IsDirty to true is to actually change\r\n    // one of the other properties on the view model. This also is good!\r\n    mvm.Name = \"Kilimanjaro\";\r\n    Debug.Assert(mvm.IsDirty.Value);\r\n    // The assert passes because we changed the mountain's name\r\n\r\nAs it currently stands, we would have to make the class slightly less readable to accomplish the same effect:\r\n\r\n    public class MountainViewModel\r\n    {\r\n        private ReactiveProperty<bool> _isDirty = new ReactiveProperty<bool>();\r\n\r\n        public ReadOnlyReactiveProperty<bool> IsDirty { get; }\r\n\r\n        public ReactiveProperty<string> Name { get; } = new ReactiveProperty<string>();\r\n\r\n        public ReactiveProperty<double> HeightInMeters { get; } = new ReactiveProperty<double>();\r\n\r\n        public MountainViewModel()\r\n        {\r\n            // This line is necessary because ReadOnlyReactiveProperty\r\n            // is not a base class of ReactiveProperty.\r\n            IsDirty = _isDirty.ToReadOnlyReactiveProperty(_isDirty.Value);\r\n\r\n            Name.Subscribe(_ => _isDirty.Value = true);\r\n            HeightInMeters.Subscribe(_ => _isDirty.Value = true);\r\n        }\r\n    }\r\n\r\nThank you for your time!"},"comment":{"url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/comments/155416448","html_url":"https://github.com/runceel/ReactiveProperty/issues/11#issuecomment-155416448","issue_url":"https://api.github.com/repos/runceel/ReactiveProperty/issues/11","id":155416448,"user":{"login":"JohnBillington","id":7782048,"avatar_url":"https://avatars.githubusercontent.com/u/7782048?v=3","gravatar_id":"","url":"https://api.github.com/users/JohnBillington","html_url":"https://github.com/JohnBillington","followers_url":"https://api.github.com/users/JohnBillington/followers","following_url":"https://api.github.com/users/JohnBillington/following{/other_user}","gists_url":"https://api.github.com/users/JohnBillington/gists{/gist_id}","starred_url":"https://api.github.com/users/JohnBillington/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohnBillington/subscriptions","organizations_url":"https://api.github.com/users/JohnBillington/orgs","repos_url":"https://api.github.com/users/JohnBillington/repos","events_url":"https://api.github.com/users/JohnBillington/events{/privacy}","received_events_url":"https://api.github.com/users/JohnBillington/received_events","type":"User","site_admin":false},"created_at":"2015-11-10T13:16:44Z","updated_at":"2015-11-10T13:16:44Z","body":"That looks perfect. Thank you so much!"}}