为什么没有订阅重载只需要一个错误处理程序?

NoP*_*God 4 c# exception-handling system.reactive

IObservable的订阅重载为Next,Next + Error,Next + Complete,Next + Complete + Error,但为什么单独只有Errors没有可观察到的?

我认为这是因为可能存在异常的IObservable,它会导致冲突,即:

IObservable<Exception> obs;
obs.Subscribe(ex => { });
Run Code Online (Sandbox Code Playgroud)

RX不知道您是否订阅了Next或Error.

有没有一种方法可以单独订阅错误而无需创建一个空的完整代表?

obs.Subscribe(
    o => { },
    ex =>
    {
        // error-handling-code
    });
Run Code Online (Sandbox Code Playgroud)

Nen*_*nad 6

好吧,这似乎是一个智力问题,所以:

从c#编译器的角度来看,对于IObservable方法签名,您提出的是(考虑到T = Exception):

public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext);
public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onError);
Run Code Online (Sandbox Code Playgroud)

两种方法重载都具有相同的签名,并且编译器不支持它.

从接口角度来看,IObserver定义如下:

public interface IObserver<in T>
{
    void OnCompleted();
    void OnError(Exception error);
    void OnNext(T value);
}
Run Code Online (Sandbox Code Playgroud)

接口的实现者必须是这样的:

public class Observer<T> : IObserver<T>
{
    public void OnCompleted()
    {
    }

    public void OnError(Exception error)
    {
        // Do something with exception
    }

    public void OnNext(T value)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,即使您未指定OnNext =()=> {},底层基础结构也必须实现它.您没有松开任何指定它的性能.

从观察者模式的逻辑角度来看,您的意图是异步订阅元素/事件序列.省略OnNext函数并仅保留OnError的方法签名会对Rx库的用户产生误导.如果你明确表明你不想做任何OnNext的意图,那就更清楚了.

一旦收到OnCompleted或OnError方法,Rx语法就保证可以认为订阅已完成.

你要做的就是制作空的foreach循环并等待异常:

try
{
    foreach (var e in sequence)
    {
        // do nothing
    }
}
catch (Exception ex)
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

这不是常见的情况.