3

事实上,我尝试对我的代码进行防错,最后让它看起来很乱。

我设置了一个功能来读取某种类型的文件。如果有问题,我希望函数返回 false,如果一切正常,我希望函数返回 true。我无法弄清楚如何构建所有内容。

我有一个尝试打开文件流的初始 try-catch 块。不过在那之后,我在读取过程中进行了某些其他检查,例如文件大小和某些偏移量的值。我设置它的方式是使用 if else 语句。如:

if(condition){

}
else{
    MessageBox.Show("There was an error");
    br.Dispose();
    fs.Dispose();
    return false;
}

...br 是二进制阅读器,fs 是文件流。有很多这样的块,多次编写相同的东西似乎是一种不好的做法。首先想到的是将整个事物包装在 try-catch 语句中并抛出异常,而不是使用 if else 块。我记得在阅读有关 try-catch 语句时,最好有它们,但不要用它们包装所有内容。老实说,我仍然不完全理解为什么将所有内容都包含在 try catch 语句中是不好的做法,因为它们仅在出现错误时才有效,在这种情况下程序无论如何都会向南...

另外,我是否必须关闭二进制读取器和文件流,或者关闭一个关闭另一个?有什么方法可以使用它们而不必处理它们?

4

5 回答 5

5

如何使用using关键字?IDisposable这包含了您在 try - finally 块中对 an 的使用;

bool success = true;

using(var fs = new FileStream(fileName, FileMode.Create)))
using(var br = new BinaryReader(fs))
{
  // do something
  success = result;
}

return success;

嵌套的 using 块将确保文件流和二进制读取器始终正确关闭和处置。

您可以阅读有关在 MSDN 中使用的更多信息。它使使用更加IDisposable整洁,消除了对显式异常处理的需要。

关于你的说法:

我记得在阅读有关 try-catch 语句时,最好有它们,但不要用它们包装所有内容。

我总是使用简单的规则,如果我无法处理特定代码块中的异常并从异常中恢复,请不要尝试捕获它。允许异常将堆栈“冒泡”到捕获它更有意义的点。使用这种方法,您会发现您不需要添加许多 try-catch 块,您将倾向于在与服务(如文件系统、网络等)集成时使用它们,但您的业务逻辑几乎总是没有异常处理机制。

于 2012-01-01T08:27:57.520 回答
1

只需using为您的一次性物品使用关键字。在using关键字的块中,您可以throw例外或return不必担心处置;它会自动为您发生。

try-catch块不是一个很好的主意,只是因为存在更好的选择:try-finally块。但是using关键字甚至更好,因为它本质上扩展为一个try-finally块并且它负责对象处理。

关闭文件流也会关闭二进制阅读器,处理它们也是如此。为什么要使用它们而不丢弃它们?处理它们更好,并且通过处理它们using是最好的事情。

于 2012-01-01T08:28:00.297 回答
0

我认为确保处理文件流的最佳方法是使用以下using块包装它们的使用

using (FileStream)
{
    ....
}
于 2012-01-01T08:28:56.987 回答
0

是的,这是不好的做法。

您应该抛出异常,而不是返回指示是否发生问题的布尔值。例子:

if (headNotValid)
   throw new Exception("Header was not valid");

在某些情况下,建议创建一个新的异常类。

使用从您继承的类时,IDisposable应使用该using指令。

using (var stream = new FileStream(filename))
{
}

这保证了您的流已被处置,即使在using块内引发异常也是如此。

总之,我更喜欢这样的东西:

private void string ParseFile(string filename)
{
     using (var stream = new FileStream(filename))
     {
           if (somethingNotValid)
              throw new Exception(...);

           return ...;
     }
}

在你的主要:

{
     try
     {
          var value = ParseFile(filename);
     }
     catch (Exception)
     {
          Console.WriteLine(..);
     }
}
于 2012-01-01T08:31:01.620 回答
0

使用using关键字。有了using你,你可以重写这样的东西:

public static int CountCars()
{
    SqlConnection conn = new SqlConnection(connectionString);
    try
    {
      SqlCommand cmd = conn.CreateCommand();
      conn.Open();
      try
      {
        cmd.CommandText = "SELECT COUNT(1) FROM Carsd";

        return (int)cmd.ExecuteScalar();
      }
      finally
      {
        if(cmd != null)
          cmd.Dispose();
      }
    }
    finally
    {
      if(cmd != null)
        conn.Dispose();
    }
}

进入这个:

public static int CountCars()
{
    using(SqlConnection conn = new SqlConnection(connectionString))
    using(SqlCommand cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "SELECT COUNT(1) FROM Carsd";

        return (int)cmd.ExecuteScalar();
    }

}

两个代码片段在编译时都会产生完全相同的 IL 代码。这些示例来自http://coding.abel.nu/2011/12/idisposable-and-using-in-c/,我在其中写了一些关于使用 and 的更多细节IDisposable

于 2012-01-01T08:55:53.300 回答