C# 用作流上Dispose的语法便利

C# 用作流上Dispose的语法便利,c#,dispose,using-statement,C#,Dispose,Using Statement,我有点困惑。我一直在花时间研究各种各样的主题,以确保我的代码是健壮的,包括IDisposable和它自己的语法糖,使用语句来确保释放非托管资源 据我所知,using被编译器翻译成try finally块,对象在try块中,调用Dispose在finally块中 根据我的理解,这将使我的以下两段代码在功能上等效- 使用 public void LoadFile(string filePath) { BinaryFormatter formatter = new BinaryFormatt

我有点困惑。我一直在花时间研究各种各样的主题,以确保我的代码是健壮的,包括
IDisposable
和它自己的语法糖
,使用
语句来确保释放非托管资源

据我所知,
using
被编译器翻译成
try finally
块,对象在
try
块中,调用
Dispose
finally
块中


根据我的理解,这将使我的以下两段代码在功能上等效-

使用

public void LoadFile(string filePath)
{
    BinaryFormatter formatter = new BinaryFormatter(); 

    if (File.Exists(filePath)) 
    { 
        using (Stream input = File.OpenRead(filePath))
        { 
            // ... 
        }
    } 
}
处置

public void LoadFile(string filePath)
{
    BinaryFormatter formatter = new BinaryFormatter(); 

    if (File.Exists(filePath)) 
    { 
        try
        {
            Stream input = File.OpenRead(filePath);
        }
        finally 
        {
            input.Dispose(); 
        }
    } 
}    

这就是我困惑的地方。在第一个示例中,使用
using
,我不确定在以这种方式构造异常处理程序时如何放入自己的异常处理程序,因为底层的
try finally
被混淆了

在第二个示例中,使用
Dispose
,我得到编译器错误“名称输入在此上下文中不存在”


显然,我不完全理解这一点。。。任何帮助都将不胜感激:)

您需要在
try
块之外声明变量,以便可以从catch和finally块访问该变量:

if (File.Exists(filePath)) 
{ 
    Stream input = null;
    try
    {
       input = File.OpenRead(filePath);
    }
    finally 
    {
        if(input != null)
           input.Dispose(); 
    }
} 

使用
使用
不会阻止您添加所需的任何异常处理:

public void LoadFile(string filePath)
{
    BinaryFormatter formatter = new BinaryFormatter(); 

    if (File.Exists(filePath)) 
    { 
        using (Stream input = File.OpenRead(filePath))
        { 
            try
            {
                // Whatever
            }

            catch (Exception exception)
            {
                // Do something with exception -
                // could log and suppress, or rethrow,
                // or whatever you need.
            }
        }
    } 
}

它只是确保无论发生什么*,文件都将被关闭


*除非出现诸如
Environment.FailFast()

之类的恶劣情况,请检查MSDN上的,以找到与.D'oh等效的实际代码。非常感谢。事实上,我打开了我面前的那一页作为参考,不知怎的,我误读了它。。。更好的是,
streaminput=File.OpenRead(filePath)尝试
之前,为简单起见,并匹配使用
@hvd的
行为,但是如果
OpenRead
引发异常,它将不在
try catch finally
块内,因此不会被处理?还是我误解了?@Eilidh是的,没错。但是,如果
OpenRead
抛出异常,
input
将不会被赋值,因此无论如何也没有任何东西可以调用
Dispose()
。@hvd确定。但是这个异常没有被处理吗?@Eilidh是的,如果你知道如何处理它的话。否则,hvd会说什么。
public void LoadFile(string filePath)
{
    BinaryFormatter formatter = new BinaryFormatter(); 

    if (File.Exists(filePath)) 
    { 
        try
        {
            using (Stream input = File.OpenRead(filePath))
            { 
                // Whatever
            }
        }

        catch (Exception exception)
        {
            // Do something with exception -
            // could log and suppress, or rethrow,
            // or whatever you need.
        }
    } 
}