Action的结果是什么?如何使用它?

时间:2016-01-22 12:27:40

标签: c# system.reactive

Reactive Extensions具有Observable.Start()功能。

Visual Studio告诉我它

  

通过可观察的序列异步调用结果。

它的返回类型为IObservable<Unit>

所有MDSN都说Unit

  

代表无效。

但为什么我需要代表void

为什么我need to convert a stream of voids to list and take first element from it to replace parallel ForEach

1 个答案:

答案 0 :(得分:6)

Reactive Extensions(或Rx)在函数式编程中非常强大,函数式编程要求每个运算符都返回一个值。

在命令式语言中,如C#,情况并非如此。我们可以定义没有返回类型的方法,如void Foo() { ... }。在非函数式语言中,这很好,当我们调用Foo()时,我们期望它做它做的任何事情并让它将控制权交还给我们。

在函数式语言中,我们可以调用void方法,因为我们需要所有东西都有一个返回类型。因此,要使Rx起作用,我们需要一个表示void的特殊返回类型,但我们不能使用void甚至实际类型System.Void作为返回类型因为编译器不允许它。所以在System.Reactive.Unit作为特殊类型来表示返回的值是void

由于可观察量均基于IObservable<T>(没有IObservable没有T),因此在调用Observable.Start(Action)时必须具有返回类型。因此,我们有IObservable<Unit>

我不明白你的意思,&#34;为什么我需要将空白流转换为列表并从中取出第一个元素来替换并行的ForEach?&#34;

  

为什么不void Start(IObservable<T>, Action<T>)

这个签名对我来说没有意义。如果您有Action<T>,那么适用的Observable.Start重载是IObservable<T> Observable.Start(Action<T>)。如果是Action(这是您提问的主题),则为IObservable<Unit> Observable.Start(Action)

  

是否有使用C#而不是其他语言使用Unit的示例?

这也是我难以理解的问题。我无法详细了解所有其他语言,以告诉您C#中专用Unit的位置。事实上,Rx与其他语言有很多端口,我认为这不是你要求的那种用法。你能澄清一下你在问什么吗?

  

有一个问题被链接询问Parallel.ForEach(IObservable<T>, Action<T>)在哪里。在答案中,使用ToList()First()查询IObservable。如果它的唯一目的是改变某些东西,那对我来说没有多大意义。

.ToList()运算符将返回零个或多个值的IObservable<T>转换为返回一个值的IObservable<IList<T>>(一旦源observable完成)。因此,以下.First()只会将IObservable<IList<T>>变为IList<T>

链接的答案已经使用它强制执行observable并阻塞直到observable完成。请记住,observable具有与enumerables相同的延迟执行模型。

  

在函数式语言中,Unit是纯函数范式和真实单词应用程序之间的折衷。它在C#中的用途是什么,从来没有纯粹的功能?

C#的功能是多么纯粹并不重要,类型Unit用于允许必须为强类型且返回零或更多值的可观察对象表示没有有意义的返回类型的类型。

它与EventArgs一个带有签名void Foo(object sender, EventArgs e)的事件处理程序非常平行 - 当事件触发时你知道发生了什么事,但是你没有得到e的信息。从可观察对象中获取Unit的值非常类似于在事件处理程序中获取EventArgs