O SqlCommand.Dispose () é necessário se o SqlConnection associado for descartado?

Eu costumo usar código como este:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) { var command = connection.CreateCommand(); command.CommandText = "..."; connection.Open(); command.ExecuteNonQuery(); } 

Meu command será automaticamente descartado? Ou não e eu tenho que envolvê-lo em bloco? É necessário eliminar o SqlCommand ?

Apenas faça isso:

 using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) using(var command = connection.CreateCommand()) { command.CommandText = "..."; connection.Open(); command.ExecuteNonQuery(); } 

Não ligar para descartar o comando não fará nada de mal. No entanto, chamar Dispose nela suprimirá a chamada para o finalizador , fazendo com que a chamada descarte um aprimoramento de desempenho.

A política mais segura é sempre chamar Dispose() em um object se ele implementar IDisposable , seja explicitamente ou por meio de um bloco de uso. Pode haver casos em que não é necessário, mas chamá-lo de qualquer maneira nunca deve causar problemas (se a class estiver escrita corretamente). Além disso, você nunca sabe quando uma implementação pode mudar, o que significa que, quando a chamada não era necessária, ela é definitivamente necessária.

No exemplo que você deu, você pode adicionar um bloco de uso interno extra para o comando, bem como manter o bloco de uso externo para a conexão.

Sim, você deve, mesmo que a implementação não esteja fazendo muito, você não sabe como ela será alterada no futuro (novas versões de framework, por exemplo). Em geral, você deve descartar todos os objects que implementam IDisposable para estar no lado seguro.

No entanto, se a operação for adiada e você não controlar o escopo completo (por exemplo, ao trabalhar de forma assíncrona ou ao retornar um SqlDataReader ou mais), será possível definir o CommandBehavior como CloseConnection para que, assim que o leitor for concluído, a conexão está devidamente fechada / descartada para você.

Na prática, você pode pular Dispose . Não libera nenhum recurso. Ele nem mesmo suprime a finalização, já que o construtor faz isso.

Em teoria, a Microsoft poderia mudar a implementação para obter um recurso não gerenciado, mas eu espero que eles saiam com uma API que se livre da class base Component muito antes deles fazerem isso.

Você pode descobrir esse tipo de coisa usando o Reflector .

Eu tive uma pequena escavação (eu sugeriria que você se esforçasse para ter certeza absoluta do resto disso, já que eu não tentei tanto) e parece que quando você mata uma conexão, não há disposição de crianças associadas. com essa conexão. Além disso, na verdade, não parece que a disposição de um comando realmente faz isso. Ele irá definir um campo como nulo, desconectar-se de um contêiner (isso pode impedir um vazamento gerenciado de memory) e gerar um evento (isso pode ser importante, mas não consigo ver quem está ouvindo esse evento).

De qualquer maneira, é uma boa prática usar essas coisas em um bloco de uso ou para garantir que você as elimine usando um padrão de descarte no object que mantém a conexão (se você pretende manter o comando por um tempo).