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

What is the result of an Action and how can I use it?

响应式扩展具有 Observable.Start() 功能。

Visual Studio 告诉我它

Invokes the action asynchronously surfacing the result through an observable sequence.

它有 return 类型 IObservable<Unit>

MDSN 关于 Unit 的所有说法都是

Represents void.

但是为什么我需要代表void

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

Reactive Extensions(或 Rx)非常依赖于函数式编程,而函数式编程要求每个运算符 return 都是一个值。

在 C# 等命令式语言中,情况并非如此。我们可以定义没有 return 类型的方法,例如 void Foo() { ... }。在 non-functional 语言中,这很好,当我们调用 Foo() 时,我们期望它做任何它做的事情并让它 return 控制我们。

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

并且由于 observables 都是基于 IObservable<T>(没有 T 就没有 IObservable),所以调用 Observable.Start(Action) 时必须有一个 return 类型.因此我们有 IObservable<Unit>.

我不明白你的意思,"Why do I need to convert a stream of voids to list and take first element from it to replace parallel ForEach?"


Why not void Start(IObservable<T>, Action<T>)?

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

Are there examples where Unit is used in C#, not some other languages?

这也是我比较难理解的问题。我不可能足够详细地了解所有其他语言来告诉您 Unit 在 C# 中专门使用的位置。事实上,Rx 到其他语言的端口太多,我认为不会有您要求的这种用法。你能澄清一下你的问题吗?

There is a question linked asking where is Parallel.ForEach(IObservable<T>, Action<T>). And in the answer, IObservable is queried with ToList() and First(). Which doesn't make a lot of sense for me if its only purpose is to mutate something.

.ToList() 运算符将 return 零个或多个值的 IObservable<T> 转换为 return 一个值的 IObservable<IList<T>> (一旦源可观察完成)。所以下面的 .First() 只是把 IObservable<IList<T>> 变成了 IList<T>.

链接的答案已使用它来强制执行可观察对象并阻塞直到可观察对象完成。请记住,可观察对象与可枚举对象具有相同的延迟执行模型。

In functional languages, Unit is a compromise between pure functional paradigm and real word applications. What is its purpose in C#, which has never been purely functional?

无论 C# 是否是纯函数式的,类型 Unit 用于允许可观察对象,它必须是 strongly-type 和 return 零个或多个值,具有指示无意义的类型 return 类型。

它与 EventArgs 具有签名 void Foo(object sender, EventArgs e) 的事件处理程序非常相似 - 当事件触发时,您知道发生了什么事,但您从 [=43= 中得不到任何信息].从可观察对象中获取 Unit 的值非常类似于在事件处理程序中获取 EventArgs