私が書いたら
using (Socket s = new Socket(/*...*/))
{
//...
}
閉じ中かっこを呼び出しますか
s.Shutdown(SocketShutdown.Both);
s.Close();
s.Dispose();
またはのみ
s.Dispose();
?
(または、他の何か ?)
ありがとうございました !
using ステートメントが呼び出さIDisposable.Dispose
れ、それだけです。
using ステートメントは、ブロックに含まれるコードがスローされ、大まかに次のように変換された場合でも、指定されたオブジェクトを常に破棄したいということをより簡潔に表現できるようにする単なるコンパイラのトリックです。
Socket s = new Socket(...)
try
{
// Code contained by the using... block here.
}
finally
{
s.Dispose();
}
Socket
私の経験では、 using ステートメントがクラスと一緒に使用されることはめったにありません。最も一般的には、Socket.Close
実際にSocket.Dispose
内部的に呼び出す のみを呼び出します。
Close
.NETDispose
のクラスで呼び出します。using ブロックSocket
はを呼び出すだけです。Dispose
しかし、これはusing ブロックが役に立たないという意味ではありません!
.NET では、using ブロックは基本的に、 using ステートメントでインターフェイスを実装するオブジェクトで呼び出されるtry /finallyの単なる構文糖衣です。以下に示して説明するように、いくつかの違いがあります。Dispose
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();
}
}
無料の null チェックを取得するだけでなく、Socket
クラスのインスタンスに追加のスコープを作成しています。
最終的に、例外がスローされた場合などにクラスのインスタンスで確実に呼び出されるため、この場合はusing ブロックを使用することをお勧めします。Dispose
Socket
この場合、 using ブロックを使用すると、得るものは多く、文字通り失うものは何もないと考えることができます。一方で、using ブロックを使用しない場合に失うものはたくさんあります。
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.