.Net 流:返回与提供

.Net streams: Returning vs Providing

我一直想知道在 C# .Net 中使用 Stream class 的最佳实践是什么。是提供一个已写入的流更好,还是提供一个? 即:

public Stream DoStuff(...)
{
    var retStream = new MemoryStream();
    //Write to retStream
    return retStream;
}

相对于;

public void DoStuff(Stream myStream, ...)
{
    //write to myStream directly
}

为了生命周期控制,我一直使用前一个例子,但我觉得 "streaming" 和 Stream 的一种糟糕的方式,因为缺少更好的词。

我更喜欢 "the second way"(在提供的流上操作),因为它有几个明显的优点:

  • 您可以拥有多态性(假设您的签名证明您可以对提供的 Stream 任何 类型进行操作)。
  • 现在或以后很容易抽象成 Stream 扩展方法。
  • 你们分工明确。此方法不应该关心如何构造 流,只关心如何对其应用特定操作。

此外,如果您要返回一个新流(选项 1),您必须先再次 Seek 才能从中读取(除非您在方法本身中执行此操作,这又是次优的,因为它可能并不总是需要的——在所有情况下可能不会在之后读取流)。在将一个已经存在的流传递给一个明确写入流的方法之后必须 Seek 似乎并不那么尴尬。

我看到 Streams 的好处是您不需要知道流式传输到什么。

在第二个示例中,您的代码可以写入内存,也可以直接写入文件或某个网络缓冲区。从函数的角度来看,实际的输出目的地可以由调用者决定。

出于这个原因,我更喜欢第二种选择。

第一个函数只是写入内存。在我看来,如果它不是 return 一个流,而是实际的内存缓冲区,那就更清楚了。如果 he/she 希望,调用者可以附加一个内存流。

public byte[] DoStuff(...)
{
    var retStream = new MemoryStream();
    //Write to retStream
    return retStream.ToArray();
}

100% 第二个。您不想假设他们想要什么样的流。他们想流式传输到网络还是磁盘?他们想让它缓冲吗?留给他们吧。

他们可能还想重用流以避免一遍又一遍地创建新缓冲区。或者他们可能希望在同一流上端到端地传输多个内容。

如果他们提供流,则他们可以控制流的类型和生命周期。否则,您还不如 return 字符串或数组之类的东西。该流并没有真正给您带来任何好处。