【问题标题】:Return the Stream directly or return a Func<Stream> when method opens up a stream方法打开流时直接返回 Stream 或返回 Func<Stream>
【发布时间】:2020-06-29 08:36:56
【问题描述】:

我有一个实现IDisposable 的类和一个返回Stream 的方法。

我想知道直接返回流更好:

public Stream GetStream()
{
     var stream = new FileStream(_fileName,  FileMode.Open);
     return stream;
}

或者最好返回一个Func&lt;stream&gt;,让调用者决定何时“触发”:

public Func<Stream> GetStream()
{
     var openStream() => new FileStream(_fileName,  FileMode.Open);
     return openStream;
}

我已经尝试过自己的研究,虽然似乎有很多类似的答案,但我还没有找到一个完全像这样的答案。查看现有答案,我仍然不确定一个是否明显优于另一个。

我认为第二种方法提供了更大的灵活性,因为我们不返回打开的流,我们打开流并允许用户在适合他们时打开流可能更可取。例如:

var listOfStreamFunc = new List<Func<Stream>>(){
   somewhere1.GetStreamFunc(),
   somewhere2.GetStreamFunc()
};

SomeMethod(listOfStreamFunc);

然后我们可以将流的打开推迟到SomeMethod,这是有利的,因为仅在必要时才打开流,同时减少了因意外过早关闭流而误用的可能性,例如

using (x = GetStream()){
   SomeMethod(x);
}

有什么理由不选择第二种选择吗?

【问题讨论】:

    标签: c# stream


    【解决方案1】:

    Func&lt;Stream&gt; 方法允许您延迟打开流,但如果您真的想延迟打开它,那么首先不要调用Stream GetStream()

    此外,如果您一直遵循您的思维过程,那么您最终会将所有内容都包装在 Func 中,例如:

    Func<int> Add(int a, int b)
    {
      var adder = () => a + b;
      return adder;
    }
    

    显然,认为用户可以调用 adder,然后在他们想要结果时“触发”它并没有什么好处!

    另外,名称GetStream 并没有记录该方法的作用(因为它没有为您提供流)。如果您希望返回 Func&lt;Stream&gt;,请给它一个更好的名称,例如:

    Func<Stream> CreateStreamOpener()
    {
      return ....
    }
    

    现在它更加明确了。

    请注意,最终这并不能降低误用的风险,因为您最终将不得不拥有一个您管理的原始 Stream 对象。

    您的类实现 IDisposable 的事实与此处无关,因为您没有保留您创建的 Stream,因此由调用者来处理流,而不是您的类。

    【讨论】:

    • “如果你真的想推迟打开它,那么首先不要调用 Stream GetStream()” - 当你这样说时,这是有道理的。如果调用者需要真正推迟执行,那么没有什么能阻止他们将该调用包装到 Func 中以实现相同的行为。同意命名及其他 - 谢谢肖恩!
    猜你喜欢
    • 2014-09-30
    • 1970-01-01
    • 2015-03-14
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 2020-06-20
    相关资源
    最近更新 更多