在Rx.NET库中提供这三种方法
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task> subscribeAsync) {...}
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<IDisposable>> subscribeAsync) {...}
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task<Action>> subscribeAsync) {...}
我在 MSVS 2013 :
中编写以下示例代码var sequence =
Observable.Create<int>( async ( observer, token ) =>
{
while ( true )
{
token.ThrowIfCancellationRequested();
await Task.Delay( 100, token );
observer.OnNext( 0 );
}
} );
由于模糊的重载,这不会编译。编译器的确切输出是:
Error 1 The call is ambiguous between the following methods or properties:
'System.Reactive.Linq.Observable.Create<int>(System.Func<System.IObserver<int>,System.Threading.CancellationToken,System.Threading.Tasks.Task<System.Action>>)'
and
'System.Reactive.Linq.Observable.Create<int>(System.Func<System.IObserver<int>,System.Threading.CancellationToken,System.Threading.Tasks.Task>)'
但是,只要我将while( true )
替换为while( false )
或var condition = true; while( condition )...
var sequence =
Observable.Create<int>( async ( observer, token ) =>
{
while ( false ) // It's the only difference
{
token.ThrowIfCancellationRequested();
await Task.Delay( 100, token );
observer.OnNext( 0 );
}
} );
错误消失,方法调用解析为:
public static IObservable<TResult> Create<TResult>(Func<IObserver<TResult>, CancellationToken, Task> subscribeAsync) {...}
那里发生了什么?
答案 0 :(得分:5)
除了@Daisy Shipton的答案之外,我想补充一点,在以下情况中也可以观察到同样的行为:
var sequence = Observable.Create<int>(
async (observer, token) =>
{
throw new NotImplementedException();
});
基本上是因为同样的原因 - 编译器看到lambda函数永远不会返回,所以任何返回类型都匹配,这反过来使lambda匹配任何Observable.Create
重载。
最后,一个简单解决方案的示例:您可以将lambda转换为所需的签名类型,以提示编译器选择哪个Rx重载。
var sequence =
Observable.Create<int>(
(Func<IObserver<int>, CancellationToken, Task>)(async (observer, token) =>
{
throw new NotImplementedException();
})
);