0

在定义变量、为它们分配空间、初始化它们然后正确清理所有内容时,我想就 C# 中的良好编程实践征求您的意见。

我目前面临的问题是,我有一个使用非托管 API 函数的函数,因此也访问了非托管内存(使用了编组)。我想让功能干净并在退出之前正确处理所有内容。但问题是,所有实际工作都是在try-catch块中完成的。这意味着我无法在catchfinally块中清理所有内容。

我所做的是声明所有变量,为它们保留内存并在进入函数后立即初始化它们,然后在finally块中清理所有内容(关闭句柄,释放内存,...)。

一切都很好,但我还希望在try块中完成变量声明、初始化和内存分配(例如,在初始化数组或在内存中分配空间或天知道在哪里时也会出错)。唯一想到的是嵌套两个try-catch块。这样可以吗,还是您会提出其他建议?

这是我到目前为止所拥有的:

//Declare variables, allocate memory, initialize variables.
........
try
{
    //Do actual work - write to file and read from a file in my case
    .........
}
catch (Exception exc)
{
    //Exception handler for file write/read errors
}
finally
{
    //Clean up (release handles, free memory,...)
}

这就是我的想法:

try
{
   //Declare variables, allocate memory, initialize variables.
   ........
   try
   {
       //Do actual work - write to file and read from a file in my case
       .........
   }
   catch (Exception exc)
   {
       //Exception handler for file write/read errors
   }
}
catch (Exception exc_1)
{
    //Exception handler for variable declaration, initialization, memory allocation errors
}
finally
{
    //Clean up (release handles, free memory,...)
}

提前感谢您的所有帮助!

干杯!

4

4 回答 4

1

您可以实现IDisposable接口以调用 Dispose 方法。

或者作为最佳实践使用块using

using (var variable = .....)
{

 ...

}

使用块的特殊性是在处理结束时调用 Dispose 方法。

例如,如果您使用SqlConnection

var(var connection = new SqlConnection("...."))
{
....

}

仅此代码就足够了

链接:http: //msdn.microsoft.com/fr-fr/library/vstudio/system.idisposable.aspx

链接:http: //msdn.microsoft.com/fr-fr/library/yh598w02%28v=vs.80%29.aspx

于 2012-09-08T12:50:09.717 回答
0

您可以根据需要嵌套任意数量的try...catch结构。这是让代码自己负责清理的好方法。

还考虑使用 justtryfinally用于始终需要清理的代码的结构,无论它是否正常:

try {

  // do something here

  // declare some variable
  try {
    // allocate space for variable
    // do something with that variable
  } fincally {
    // deallocate space for variable
  }

  // do something more here

} catch(Exception ex) {
  // handle the exception here
}

您应该尝试使用尽可能具体的异常类,并且可以在同一结构中使用不同的类型来捕获不同的异常:

try {
  // do some i/o
} catch (IOException ex) {
  // here you know that it was actually the i/o that failed
} catch (Exception ex) {
  // here is for catching anything else that might have failed
}
于 2012-09-08T13:12:11.783 回答
0

这种方法的问题是变量在finally(和catch)中超出范围

    try
    {
        string testString;
    }
    catch (Exception ex)
    {
    }
    finally
    {
        // testString is not in scope
    }

您担心声明可能会引发运行时错误?

根据评论 OP 不知道初始化可以与声明分开。

    List<string>  testLString;        
    try
    {
        testLString = new List<string>();
    }
    catch (Exception ex)
    {
    }
    finally
    {
        testLString = null;
    }

我不同意您对声明可能引发运行时错误的担忧。
它除了声明什么都不做。

于 2012-09-08T13:00:31.293 回答
0

我建议您创建一个单独的类型,它包含与非托管 API 的所有通信、管理内存等。它实现了接口,该IDisposable接口的实现负责清理所有非托管资源。如果你在 Windows 上,最简单的方法是在 C++/CLI 中实现这个包装器。

于 2012-09-08T13:15:45.400 回答