C# 对using子句中的类调用Close是有益的、有害的还是没有意义的?

C# 对using子句中的类调用Close是有益的、有害的还是没有意义的?,c#,serial-port,using-statement,opennetcf,C#,Serial Port,Using Statement,Opennetcf,在重构一些代码时,我添加了一个using语句,如下所示: using (SerialPort serialPort = new SerialPort()) { serialPort.BaudRate = 19200; serialPort.Handshake = Handshake.XOnXOff; serialPort.Open(); serialPort.Write(cmd); serialPort.Close(); } …但现在我想知道我是否可以或

在重构一些代码时,我添加了一个using语句,如下所示:

using (SerialPort serialPort = new SerialPort())
{
    serialPort.BaudRate = 19200;
    serialPort.Handshake = Handshake.XOnXOff;
    serialPort.Open();
    serialPort.Write(cmd);
    serialPort.Close();
}

…但现在我想知道我是否可以或应该取消关闭电话。我想是的,但这仅仅是一个精确的样式点还是一个真正的必要性?

这实际上取决于类以及作者是否按照建议实现了它-正确地实现了IDisposable,并让Close除了调用Dispose之外什么都不做。在这种情况下,Close调用是多余的,可以在using块中包装类时删除


一般来说,在SerialPort的这种特定情况下,他们这样做了,因此Close调用是多余的,可以删除。

这实际上取决于类,如果作者按照建议实现了它,则正确实现了IDisposable,并且Close只执行调用Dispose。在这种情况下,Close调用是多余的,可以在using块中包装类时删除


一般来说,在SerialPort的这种特定情况下,他们这样做了,因此Close调用是多余的,可以删除。

这实际上取决于实现IDisposable的特定类。对于一个实现IDisposable的编写糟糕的类来说,完全有可能不正确地释放资源和关闭连接。在SerialPort类的特定情况下,文档说明Close调用是Dispose。我认为在这种情况下,您可以将它放在using块中,而不是手动调用Close。

这实际上取决于实现IDisposable的特定类。对于一个实现IDisposable的编写糟糕的类来说,完全有可能不正确地释放资源和关闭连接。在SerialPort类的特定情况下,文档说明Close调用是Dispose。我认为在这种情况下,您可以将其放在使用块中,而不是手动调用Close。

根据里氏:

提供确定性处置功能的类型,或 关闭并实现dispose模式。dispose模式定义了 开发人员在定义 希望为该类型的用户提供显式清理

由于SerialPort定义了打开和关闭,这意味着它可以在其生命周期内多次打开和关闭,这与它被处置是相互排斥的,例如,不再使用

但是回到您最初的问题,是的-在这种情况下是多余的,反编译SerialPort对象会显示dispose在调用时为您关闭端口:

protected override void Dispose(bool disposing)
{
  if (disposing && this.IsOpen)
  {
    this.internalSerialStream.Flush();
    this.internalSerialStream.Close();
    this.internalSerialStream = (SerialStream) null;
  }
  base.Dispose(disposing);
}
根据里希特:

提供确定性处置功能的类型,或 关闭并实现dispose模式。dispose模式定义了 开发人员在定义 希望为该类型的用户提供显式清理

由于SerialPort定义了打开和关闭,这意味着它可以在其生命周期内多次打开和关闭,这与它被处置是相互排斥的,例如,不再使用

但是回到您最初的问题,是的-在这种情况下是多余的,反编译SerialPort对象会显示dispose在调用时为您关闭端口:

protected override void Dispose(bool disposing)
{
  if (disposing && this.IsOpen)
  {
    this.internalSerialStream.Flush();
    this.internalSerialStream.Close();
    this.internalSerialStream = (SerialStream) null;
  }
  base.Dispose(disposing);
}

如果在Dispose中出现异常情况,通常最好让Dispose抛出异常,而不是静默完成。在任何特定情况下抑制异常是否更好取决于异常是否已挂起,而且目前还没有Dispose可以知道何时发生的机制。由于在Dispose中没有处理异常的好方法,因此通常最好在调用Dispose之前,尽可能确保在Dispose中执行任何可能出错的操作

如果Dispose是正常情况下唯一的清理方法,那么让它扼杀异常将带来重大风险,即问题可能会发生,但无法被发现。让一个类同时支持Close和using,并且让客户机在主线情况下调用Close,将允许降低这种风险。如果异常挂起,Dispose将在不关闭的情况下被调用,因此清理时的任何异常都将被抑制,但代码将知道由于挂起的异常而在某个地方出错;如果在关闭之前没有发生异常,那么在Dispose cleanup上下文中没有调用它这一事实将意味着它可以假定没有任何异常处于挂起状态,因此它可以安全地抛出自己的异常

Dispose和Close的异常处理实践没有多少一致性,但我建议原则上调用Close。根据Dispose和Close的实现方式,在隐式Dispose之前显式调用Close可能会有帮助,也可能没有帮助,但最坏情况下应该是无害的。如果在类的当前版本中,或者在将来的版本I中,它可能会有所帮助
建议将其作为一般习惯。

如果处置过程中出现异常情况,让Dispose抛出异常通常比无声地完成要好。在任何特定情况下抑制异常是否更好取决于异常是否已经挂起,而且目前还没有Dispose可以知道何时发生的机制。由于在Dispose中没有处理异常的好方法,因此通常最好在调用Dispose之前,尽可能确保在Dispose中执行任何可能出错的操作

如果Dispose是正常情况下唯一的清理方法,那么让它扼杀异常将带来重大风险,即问题可能会发生,但无法被发现。让一个类同时支持Close和using,并且让客户机在主线情况下调用Close,将允许降低这种风险。如果异常挂起,Dispose将在不关闭的情况下被调用,因此清理时的任何异常都将被抑制,但代码将知道由于挂起的异常而在某个地方出错;如果在关闭之前没有发生异常,那么在Dispose cleanup上下文中没有调用它这一事实将意味着它可以假定没有任何异常处于挂起状态,因此它可以安全地抛出自己的异常


Dispose和Close的异常处理实践没有多少一致性,但我建议原则上调用Close。根据Dispose和Close的实现方式,在隐式Dispose之前显式调用Close可能会有帮助,也可能没有帮助,但最坏情况下应该是无害的。如果在当前版本的课程中没有,它可能会有所帮助,也许在将来的版本中,我会建议将其作为一种普遍的习惯。

LOL我们几乎写了完全相同的答案。我希望其他人不会给出更好的答案。我很好奇谁能在这里得到答案。当时间和内容/可用性都很差的时候,我通常会以更少的分数给猫。哈哈,我们几乎写了完全相同的答案。我希望其他人不会给出更好的答案。我很好奇谁赢了,谁能在这里得到答案。当时间和内容/可用性都很困难时,我通常会以较少的分数给猫。是的,你可以非常肯定微软编写的任何类都能正确处理。是的,你可以非常肯定,微软编写的任何类都能正确地处理。在我的例子中,我的方法被多次调用时遇到了一个File 55错误,所以我试图找到一种方法来驯服这个怪兽。我应该考虑引用里希特,因为我得到了类似地震的结果。在我的例子中,当我的方法被多次调用时,我遇到了一个File 55错误,所以我试图找到一种驯服这头野兽的方法。我本应该考虑参考里希特,因为我得到了类似地震的结果。