返回在'using'语句中创建的实例

Ahm*_*met 4 c# using

如果我有这个方法:

public StreamReader GetResourceStream(string filename)
{
    using (Stream stream = this.GetType().Assembly.GetManifestResourceStream(filename))
    using (StreamReader sr = new StreamReader(stream))
    {
        return sr;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我打电话给它时,我应该这样称呼它

StreamReader resource = GetResourceStream("blah.xml");
Run Code Online (Sandbox Code Playgroud)

或者这样:

using (StreamReader resource = GetResourceStream("blah.xml"))
{
    // Do stuff
}
Run Code Online (Sandbox Code Playgroud)

如果是第二种方式,这是否意味着该using (StreamReader sr = new StreamReader(stream))线路没有使用using声明产生任何差异?

Jon*_*eet 7

您应该更改方法本身包含using语句,但请确保调用代码使用using语句:

public StreamReader GetResourceStream(string filename)
{
    return new StreamReader(GetType().Assembly
                                     .GetManifestResourceStream(filename));
}

using (StreamReader resource = GetResourceStream("blah.xml"))
{
    // Do stuff
}
Run Code Online (Sandbox Code Playgroud)

这样它只会在你实际使用它时处理掉它.基本上,该方法将返回资源的所有权授予调用者.这还不算太糟糕 - 它是相当普遍的,甚至(想想File.OpenText等).

当您将资源传递给方法或构造函数时,它变得更加棘手- "被调用"代码是否应该取得所有权?通常不会,但偶尔也是合适的 - 例如,Bitmap(Stream)文档声明只要需要位图,就必须保持流的活动状态.实际上,处理位图也会处理流,因此您仍然只有一个资源可以跟踪...但您确实需要知道不能关闭流.


Pau*_*ips 3

GetResourceStream让该方法将 using 语句放在它返回的对象周围并没有真正的意义。这意味着您将返回处于已处置状态的对象,这有什么好处呢?它会给ObjectDisposed你抛出异常。

因此,请删除using工厂方法中的语句,然后using在实际使用该语句的地方应用该语句。

它应该看起来更像这样:

public StreamReader GetResourceStream(string filename)
{
    Stream stream = this.GetType().Assembly.GetManifestResourceStream(filename);
    return new StreamReader(stream)        
}
Run Code Online (Sandbox Code Playgroud)

  • @Ahmet 两个代码示例都创建了一个“Stream”。`StreamReader` 可能在底层流被释放时调用 dispose,尽管我还没有找到显示这一点的文档。 (2认同)