2

如果我写

using (Socket s = new Socket(/*...*/))
{
    //...
}

右括号是否调用

s.Shutdown(SocketShutdown.Both);
s.Close();
s.Dispose();

或者只有

s.Dispose();

?

(或者是其他东西 ?)

谢谢 !

4

3 回答 3

2

using 语句将调用IDisposable.Dispose,仅此而已。

using 语句只是一个编译器技巧,它允许您更简洁地表达您总是希望处理给定对象,即使该块包含的代码抛出并粗略地转换为以下内容

Socket s = new Socket(...)
try
{
   // Code contained by the using... block here. 
}
finally
{
   s.Dispose();
}

根据我的经验,using 语句很少与Socket类一起使用。大多数情况下,您只会调用Socket.Closewhich 将在Socket.Dispose内部实际调用。

于 2013-10-16T20:35:45.530 回答
1

Close在 .NETDispose中的类中调用。using 块只是调用Socket.Dispose

但这并不意味着using 块没有用!

在 .NET 中,using 块本质上只是try/finally的语法糖,在using 语句中实现接口Dispose的对象上调用where 。正如我在下面说明和解释的那样,存在一些差异。IDisposable

以下代码:

using (var socket = new Socket(/*...*/))
{
    // operations
    socket.Shutdown(SocketShutdown.Both);
    socket.Close();
}

在编译时扩展为以下代码:

{
  Socket socket = new Socket(/*...*/);
  try
  {
      // operations
      socket.Shutdown(SocketShutdown.Both);
      socket.Close();
  }
  finally
  {
    if (socket != null)
      ((IDisposable)socket).Dispose();
  }
}

您不仅获得了免费的空检查,而且还为您的Socket类实例创建了一个额外的范围。

最终,我建议在这种情况下使用 using 块,因为它确保在抛出异常等情况下Dispose在类的实例上调用它。Socket

在这种情况下使用 using 块时,我可以想出很多收获,实际上没有什么损失。另一方面,当不使用using 块时,我会想到很多损失。

于 2013-10-16T20:37:12.707 回答
0

If you look at the code of Socket in ILSpy or Reflector.NET you will see the following code:

public void Close()
{
    if (Socket.s_LoggingEnabled)
    {
        Logging.Enter(Logging.Sockets, this, "Close", null);
    }
    ((IDisposable)this).Dispose();
    if (Socket.s_LoggingEnabled)
    {
        Logging.Exit(Logging.Sockets, this, "Close", null);
    } 
}

Essentially calling Dispose() is redundant. Calling Close() is enough.

于 2013-10-16T20:39:12.160 回答