C# “如何结合”;IObservable<;布尔>;IsActive";及;“bool IsEnabled”;一分为二
有两个属性,一个是C# “如何结合”;IObservable<;布尔>;IsActive";及;“bool IsEnabled”;一分为二,c#,reactive-programming,system.reactive,rx.net,C#,Reactive Programming,System.reactive,Rx.net,有两个属性,一个是public-IObservable-isnabled{get;set;}类型,另一个是public-bool-IsActive{get;set;}类型,我想使用System.Reactive将这两个属性组合在一个属性中,就像public-bool-IsActiveAndEnabled{get;set;} public class BindableProperty<T> { T Value { get; } } public class Manager
public-IObservable-isnabled{get;set;}
类型,另一个是public-bool-IsActive{get;set;}
类型,我想使用System.Reactive
将这两个属性组合在一个属性中,就像public-bool-IsActiveAndEnabled{get;set;}
public class BindableProperty<T>
{
T Value { get; }
}
public class Manager
{
public IObservable<bool> IsEnabled { get; set; }
public BindableProperty<bool> IsActiveAndEnabled { get; set; }
private bool isActive;
public bool IsActive
{
get { return isActive; }
set
{
isActive = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged(() => IsActive);
}
}
private void OnPropertyChanged(Func<bool> property)
{
throw new NotImplementedException();
}
public Manager()
{
IsEnabled
.And(/* accept only observable, but I want to join with IsActive*/)
.Then((isEnabled,isActive) => IsActiveAndEnabled = isEnabled && isActive);
}
}
公共类BindableProperty
{
T值{get;}
}
公共班级经理
{
公共IObservable IsEnabled{get;set;}
public BindableProperty IsActiveAndEnabled{get;set;}
私人住宅是活跃的;
公共福利活动
{
获取{return isActive;}
设置
{
i活跃=价值;
//每当更新属性时调用OnPropertyChanged
OnPropertyChanged(()=>IsActive);
}
}
私有void OnPropertyChanged(Func属性)
{
抛出新的NotImplementedException();
}
公共经理()
{
我迷路了
.和(/*只接受可观察,但我想加入IsActive*/)
。然后((isEnabled,isActive)=>IsActivateAndEnabled=isEnabled&&isActive);
}
}
- 您发布的代码不是如何使用反应式编程范例的好例子
- 请不要将“可观察”视为类a可变对象的单个标量值成员属性的视图。
- 我责怪微软让人们产生这种误解,因为多年前他们在.NET框架中添加了
,但他们(错误地)在observateCollection
上下文中使用了“observate”一词,这与反应式编程中的observateCollection
的含义完全无关observateCollection
- 我责怪微软让人们产生这种误解,因为多年前他们在.NET框架中添加了
- 请不要将“可观察”视为类a可变对象的单个标量值成员属性的视图。
- 在执行反应式编程时,可观察对象是数据对象流的源(或发射器)(请注意,流可以是空的(从不发射任何东西),或者在关闭自身之前只发射单个对象,或者每秒发射数千个对象)
- 因此,
最好被认为是一个“IObservable
”,它推动(与具有“pull”语义的正常IEnumerable
相比)IEnumerable
- 另一件重要的事情是,可观测对象发出的对象应该(不,必须)是不可变的或者至少,发出的对象不能与任何其他发出的对象共享可变状态!
- 这是因为如果一个值随着时间的推移而改变,或者如果对一个对象的更改会影响其他对象,那么程序中使用返回对象的不同实例的其他部分的状态将发生变化,而不会发生预期的变化
Observable
而不是Promise
后,这一功能得到了普及。虽然许多指南都涉及RxJS,但它们完全适用于其他平台(如.NET)的反应式编程(虽然IObservable
是.NET Framework的一部分,但您需要单独的反应式扩展库来正确地进行反应式编程,而无需重新发明轮子)
重要提示:(存在切向关系,但它们是完全独立的事物)
资源:
- 导言:
- .NET的反应式扩展:
必须是可变的:
- Remove
public IObservable IsEnabled{get;set;}
- 定义一个新的不可变的
类管理器状态
- 扩展
类管理器:IObservable
- 每当
类管理器
中的可变属性发生更改时,向订阅服务器发送一个新的管理器状态
(使用管理器
的快照副本填充)
如果类管理器
可以设置为不可变:
- Remove
public IObservable IsEnabled{get;set;}
- 定义一个新类
ManagerSource
,它实现了IObservable
- 每次以某种方式更新
管理器
时,向订阅服务器发送一个新的管理器
对象(用管理器
的快照副本填充)
示例(当类管理器
是可变的时):
听起来这是一个很有价值的目标。你被困在哪里了?你能给我们看看你的实际代码而不是一堆属性签名吗?你被困在哪里了?嗨@Enigmativity,我提供了更多的信息,希望我说得很清楚。你确定要在IObservable
中放一个标量值而不是主题类型吗?不清楚是什么BindableProperty
是或如何更新它,因此我将假定一个普通属性的形式为public bool IsActiveAndEnabled{get;private set;}
。在这种情况下,IsEnabled.StartWith(true).Subscribe(IsEnabled=>IsActiveAndEnabled=IsEnabled&&IsActivity)
为您工作?是的,我认为微软引入IAsyncEnumerable会让事情变得更加混乱,在我看来,IAsyncEnumerable试图实现与可观测流相同的目的,但具有异步延续性。@Frank imhoIAsyncEnumerable
非常容易理解。@Asti我觉得虽然IAsyncEnumerable是可以理解的,但它是c我同意的一点是,先生,你是一位学者,也是一位绅士。我唯一的遗憾是,我只能投一票
class Manager : IObservable<ManagerState>
{
private Boolean isEnabled; // backing field
public Boolean IsEnabled
{
get { return this.isEnabled; }
set
{
this.isEnabled = value;
this.NotifySubscribers();
}
}
private Boolean isActive; // backing field
public Boolean IsActive
{
get { return this.isActive; }
set
{
this.isActive = value;
this.NotifySubscribers();
}
}
#region Observers (Subscribers) handling:
private readonly ConcurrentBag<IObserver<ManagerState>> subscribers = new ConcurrentBag<IObserver<ManagerState>>();
private void NotifySubscribers()
{
ManagerState snapshot = new ManagerState(
this.IsEnabled,
this.IsActive,
// etc
);
foreach( IObserver<ManagerState> observer in this.subscribers )
{
observer.OnNext( snapshot );
}
}
#endregion
}
// Represents a snapshot of the state of a `Manager`
class ManagerState
{
public ManagerState( Boolean isEnabled, Boolean isActive )
{
this.IsEnabled = isEnabled;
this.IsActive = isActive;
}
public Boolean IsEnabled { get; }
public Boolean IsActive { get; }
// any other members, etc
}
class Manager : IObservable<ManagerState>, INotifyPropertyChanged
{
private Boolean isEnabled; // backing field
public Boolean IsEnabled
{
get { return this.isEnabled; }
set
{
this.isEnabled = value;
this.OnPropertyChanged( nameof(this.IsEnabled) );
}
}
private Boolean isActive; // backing field
public Boolean IsActive
{
get { return this.isActive; }
set
{
this.isActive = value;
this.OnPropertyChanged( nameof(this.IsActive) );
}
}
#region INotifyPropetyChanged and Observers (Subscribers) handling:
private readonly ConcurrentBag<IObserver<ManagerState>> subscribers = new ConcurrentBag<IObserver<ManagerState>>();
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged( String name )
{
// First, notify users of INotifyPropetyChanged:
this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( name ) );
// Then notify users of IObservable:
ManagerState snapshot = new ManagerState(
this.IsEnabled,
this.IsActive,
// etc
);
foreach( IObserver<ManagerState> observer in this.subscribers )
{
observer.OnNext( snapshot );
}
}
#endregion
}