.Net streams: Returning vs Providing
Asked Answered
R

3

12

I have always wondered what the best practice for using a Stream class in C# .Net is. Is it better to provide a stream that has been written to, or be provided one? i.e:

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

as opposed to;

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

I have always used the former example for sake of lifecycle control, but I have this feeling that it a poor way of "streaming" with Stream's for lack of a better word.

Resistor answered 22/3, 2015 at 21:32 Comment(0)
L
11

I would prefer "the second way" (operate on a provided stream) since it has a few distinct advantages:

  • You can have polymorphism (assuming as evidenced by your signature you can do your operations on any type of Stream provided).
  • It's easily abstracted into a Stream extension method now or later.
  • You clearly divide responsibilities. This method should not care on how to construct a stream, only on how to apply a certain operation to it.

Also, if you're returning a new stream (option 1), it would feel a bit strange that you would have to Seek again first in order to be able to read from it (unless you do that in the method itself, which is suboptimal once more since it might not always be required - the stream might not be read from afterwards in all cases). Having to Seek after passing an already existing stream to a method that clearly writes to the stream does not seem so awkward.

Lui answered 22/3, 2015 at 21:42 Comment(1)
Say, hypothetically, I want to perform a streamed action that is apart of a greater return structure? For example: IResponseObject DoThingWithStream(//args) Does this affect the approach?Resistor
C
6

I see the benefit of Streams is that you don't need to know what you're streaming to.

In the second example, your code could be writing to memory, it could be writing directly to file, or to some network buffer. From the function's perspective, the actual output destination can be decided by the caller.

For this reason, I would prefer the second option.

The first function is just writing to memory. In my opinion, it would be clearer if it did not return a stream, but the actual memory buffer. The caller can then attach a Memory Stream if he/she wishes.

public byte[] DoStuff(...)
{
    var retStream = new MemoryStream();
    //Write to retStream
    return retStream.ToArray();
}
Commence answered 22/3, 2015 at 21:46 Comment(4)
Side note: GetBuffer() returns internal buffer of MemoryStream, you'd usually want to return ToArray() to cut off unwritten portion of stream.Signorina
@AlexeiLevenkov Thanks, I've incorporated your feedback into the answerCommence
I mean MemoryStream.ToArray (edited, feel free to rollback).Signorina
@AlexeiLevenkov - Yes, of course, I was just copying the entire bufferCommence
I
0

100% the second one. You don't want to make assumptions about what kind of stream they want. Do they want to stream to the network or to disk? Do they want it to be buffered? Leave these up to them.

They may also want to reuse the stream to avoid creating new buffers over and over. Or they may want to stream multiple things end-to-end on the same stream.

If they provide the stream, they have control over its type as well as its lifetime. Otherwise, you might as well just return something like a string or array. The stream isn't really giving you any benefit over these.

Interferon answered 5/11, 2019 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.