通常,IDisposable
块的using
对象本身是由另一个IDisposable
对象(例如
using (FileStream stream = File.Open(path, FileMode.Open))
using (MyObject obj = new MyObject(stream))
{
// do something with obj
}
不幸的是,上面的代码使文件流保持打开状态,直到MyObject
对象被处置为止。
要在MyObject
构造函数完成后立即处理文件流,我可以改写:
MyObject CreateMyObject(string path)
{
using (FileStream stream = File.Open(path, FileMode.Open))
{
return new MyObject(stream);
}
}
using (MyObject obj = CreateMyObject(path))
{
// do something with obj
}
但是我不喜欢这种解决方案的冗长。我尝试用lambda替换CreateMyObject()
,但是找不到合法的语法。有没有一种方法,而无需调用自定义创建函数?
编辑:请牢记一些评论,我应该指出,我正在尝试避免使用try
... finally
-这是产生using
的主要原因首先阻止。
其他说明:MyObject对象是根据流中的信息构造的,即,其构造函数以其整体来读取流的内容。 MyObject中没有其他方法引用该流。流的内容可能来自任何地方-文件,资源,Internet套接字等。
答案 0 :(得分:2)
您可以像这样调用一些魔术:
TResult CreateUsingDisposable<TDisposable, TResult>(TDisposable disposable, Func<TDisposable, TResult> getResult)
where TDisposable : IDisposable
{
using (disposable)
{
return getResult(disposable);
}
}
using (var obj = CreateUsingDisposable(new FileStream(path, FileMode.Open), stream => new MyObject(stream)))
{
}
但是为什么呢?有一种超级简单易懂的方法:
MyObject obj;
using (var stream = new FileStream(path, FileMode.Open))
{
obj = new MyObject(stream);
}
using (obj)
{
}
答案 1 :(得分:1)
虽然我看不到一种避免使用creator函数的方法,但您可以使其通用到足以定义一次并用于任何类:
static T WithStream<T>(string path, Func<FileStream, T> getter)
{
using (FileStream stream = File.Open(path, FileMode.Open))
{
return getter(stream);
}
}
class MyObject : IDisposable
{
public MyObject (Stream stream){ /* Work with stream */}
public void Dispose(){}
}
static void Main()
{
using (MyObject obj = WithStream("path", fs => new MyObject(fs)))
{
// do something with obj
}
}