Domanda

Utente kokos rispose il meraviglioso Funzionalità nascoste di C# domanda menzionando il using parola chiave.Puoi approfondire questo argomento?A cosa servono using?

È stato utile?

Soluzione

Il motivo del using L'istruzione serve a garantire che l'oggetto venga eliminato non appena esce dall'ambito e non richiede codice esplicito per garantire che ciò accada.

Come in Comprendere l'istruzione 'using' in C#, il CLR .NET converte

using (MyResource myRes = new MyResource())
{
    myRes.DoSomething();
}

A

{ // Limits scope of myRes
    MyResource myRes= new MyResource();
    try
    {
        myRes.DoSomething();
    }
    finally
    {
        // Check for a null resource.
        if (myRes != null)
            // Call the object's Dispose method.
            ((IDisposable)myRes).Dispose();
    }
}

Altri suggerimenti

Dal momento che molte persone lo fanno ancora:

using (System.IO.StreamReader r = new System.IO.StreamReader(""))
using (System.IO.StreamReader r2 = new System.IO.StreamReader("")) {
   //code
}

Immagino che molte persone ancora non sappiano che puoi fare:

using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) {
   //code
}

Cose come queste:

using (var conn = new SqlConnection("connection string"))
{
   conn.Open();

    // Execute SQL statement here on the connection you created
}

Questo SqlConnection verrà chiuso senza bisogno di chiamare esplicitamente il .Close() funzione, e questo accadrà anche se viene lanciata un'eccezione, senza la necessità di a try/catch/finally.

using può essere utilizzato per chiamare IDisposable.Può essere utilizzato anche per i tipi di alias.

using (SqlConnection cnn = new SqlConnection()) { /*code*/}
using f1 = System.Windows.Forms.Form;

utilizzando, nel senso di

using (var foo = new Bar())
{
  Baz();
}

In realtà è una scorciatoia per provare/finalmente bloccare.È equivalente al codice:

var foo = new Bar();
try
{
  Baz();
}
finally
{
  foo.Dispose();
}

Noterai, ovviamente, che il primo frammento è molto più conciso del secondo e anche che ci sono molti tipi di cose che potresti voler fare come pulizia anche se viene lanciata un'eccezione.Per questo motivo abbiamo creato una classe che chiamiamo Scope che consente di eseguire codice arbitrario nel metodo Dispose.Quindi, ad esempio, se avessi una proprietà chiamata IsWorking che volessi sempre impostare su false dopo aver tentato di eseguire un'operazione, lo faresti in questo modo:

using (new Scope(() => IsWorking = false))
{
  IsWorking = true;
  MundaneYetDangerousWork();
}

Puoi leggere ulteriori informazioni sulla nostra soluzione e su come l'abbiamo ricavata Qui.

L'ho usato molto in passato per lavorare con flussi di input e output.Puoi nidificarli bene e questo elimina molti dei potenziali problemi che di solito incontri (chiamando automaticamente dispose).Per esempio:

        using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
        {
            using (BufferedStream bs = new BufferedStream(fs))
            {
                using (System.IO.StreamReader sr = new StreamReader(bs))
                {
                    string output = sr.ReadToEnd();
                }
            }
        }

La documentazione Microsoft lo afferma utilizzando ha una doppia funzione (https://msdn.microsoft.com/en-us/library/zhdeatwt.aspx), sia come a direttiva e dentro dichiarazioni.Come un dichiarazione, come è stato sottolineato qui in altre risposte, la parola chiave è fondamentalmente zucchero sintattico per determinare un ambito per smaltire un Monouso oggetto.Come un direttiva, viene abitualmente utilizzato per importare spazi dei nomi e tipi.Anche come direttiva, puoi creare alias per spazi dei nomi e tipi, come sottolineato nel libro "C# 5.0 In a Nutshell:La guida definitiva" (http://www.amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8), di Joseph e Ben Albahari.Un esempio:

namespace HelloWorld
{
    using AppFunc = Func<IDictionary<DateTime, string>, List<string>>;
    public class Startup
    {
        public static AppFunc OrderEvents() 
        {
            AppFunc appFunc = (IDictionary<DateTime, string> events) =>
            {
                if ((events != null) && (events.Count > 0))
                {
                    List<string> result = events.OrderBy(ev => ev.Key)
                        .Select(ev => ev.Value)
                        .ToList();
                    return result;
                }
                throw new ArgumentException("Event dictionary is null or empty.");
            };
            return appFunc;
        }
    }
}

Questo è qualcosa da adottare con saggezza, poiché l'abuso di questa pratica può danneggiare la chiarezza del proprio codice.C'è una bella spiegazione sugli alias C#, che menziona anche pro e contro, in DotNetPearls (http://www.dotnetperls.com/using-alias).

Aggiungo solo qualcosa che mi ha sorpreso e non è venuta fuori.La caratteristica più interessante dell'utilizzo (secondo me) è che, indipendentemente da come si esce dal blocco using, l'oggetto verrà sempre eliminato.Ciò include resi ed eccezioni.

using (var db = new DbContext())
{
    if(db.State == State.Closed) throw new Exception("Database connection is closed.");
    return db.Something.ToList();
}

Non importa se viene lanciata l'eccezione o se viene restituito l'elenco.L'oggetto DbContext verrà sempre eliminato.

Un altro ottimo utilizzo di using è quando si crea un'istanza di una finestra di dialogo modale.

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using

In conclusione, quando si utilizza una variabile locale di tipo che implementa IDisposable, Sempre, senza eccezione, utilizzare using1.

Se usi nonlocal IDisposable variabili, quindi Sempre implementare il IDisposable modello.

Due semplici regole, nessuna eccezione1.Prevenire altrimenti le perdite di risorse è una vera seccatura *ss.


1):L'unica eccezione è quando gestisci le eccezioni.Potrebbe quindi essere necessario meno codice da chiamare Dispose esplicitamente nel finally bloccare.

È interessante notare che puoi anche utilizzare il modello using/IDisposable per altre cose interessanti (come l'altro punto in cui Rhino Mocks lo utilizza).Fondamentalmente, puoi trarre vantaggio dal fatto che il compilatore lo farà Sempre call .Dispose sull'oggetto "usato".Se hai qualcosa che deve accadere dopo una determinata operazione...qualcosa che ha un inizio e una fine definiti...quindi puoi semplicemente creare una classe IDisposable che avvii l'operazione nel costruttore e quindi termini nel metodo Dispose.

Ciò ti consente di utilizzare la sintassi using davvero carina per denotare l'inizio e la fine espliciti di detta operazione.Questo è anche il modo in cui funziona il materiale System.Transactions.

È possibile utilizzare lo spazio dei nomi alias tramite il seguente esempio:

using LegacyEntities = CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects;

Questo è chiamato a utilizzando la direttiva alias Per quanto puoi vedere, può essere usato per nascondere riferimenti prolissi se vuoi renderlo ovvio nel tuo codice a cosa ti riferisci a EG

LegacyEntities.Account

invece di

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

o semplicemente

Account   // It is not obvious this is a legacy entity

Quando si utilizza ADO.NET è possibile utilizzare la chiave per cose come l'oggetto connessione o l'oggetto lettore.In questo modo, una volta completato il blocco di codice, la connessione verrà eliminata automaticamente.

"using" può essere utilizzato anche per risolvere i conflitti dello spazio dei nomi.Vedere http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflitti/ per un breve tutorial che ho scritto sull'argomento.

public class ClassA:IDisposable

{
   #region IDisposable Members        
    public void Dispose()
    {            
        GC.SuppressFinalize(this);
    }
    #endregion
}

public void fn_Data()

    {
     using (ClassA ObjectName = new ClassA())
            {
                //use objectName 
            }
    }

utilizzando viene utilizzato quando si dispone di una risorsa che si desidera smaltire dopo essere stata utilizzata.

Ad esempio, se assegni una risorsa File e devi utilizzarla solo in una sezione di codice per un po' di lettura o scrittura, l'utilizzo è utile per eliminare la risorsa File non appena hai finito.

La risorsa utilizzata deve implementare IDisposable per funzionare correttamente.

Esempio:

using (File file = new File (parameters))
{
    *code to do stuff with the file*
}

La parola chiave using definisce l'ambito dell'oggetto e quindi elimina l'oggetto quando l'ambito è completo.Per esempio.

using (Font font2 = new Font("Arial", 10.0f))
{
    // use font2
}

Vedere Qui per l'articolo MSDN sulla parola chiave C# using.

Non che sia molto importante, ma l'utilizzo può essere utilizzato anche per modificare le risorse al volo.Sì, usa e getta, come accennato in precedenza, ma forse nello specifico non vuoi che le risorse non corrispondano ad altre risorse durante il resto dell'esecuzione.Quindi vuoi smaltirlo in modo che non interferisca altrove.

Grazie ai commenti qui sotto, ripulirò un po' questo post (non avrei dovuto usare le parole 'raccolta dei rifiuti' in quel momento, mi scuso):
Quando usi using, chiamerà il metodo Dispose() sull'oggetto alla fine dell'ambito di using.Quindi puoi avere un bel po' di ottimo codice di pulizia nel tuo metodo Dispose().
Un punto elenco qui che, si spera, potrebbe ottenere questo non segnato:Se implementi IDisposable, assicurati di chiamare GC.SuppressFinalize() nella tua implementazione Dispose(), altrimenti la garbage collection automatica proverà ad arrivare e finalizzarla ad un certo punto, il che almeno sarebbe uno spreco di risorse se tu ne ho già smaltito.

Altro esempio di uso ragionevole in cui l'oggetto viene immediatamente smaltito:

using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString)) 
{
    while (myReader.Read()) 
    {
        MyObject theObject = new MyObject();
        theObject.PublicProperty = myReader.GetString(0);
        myCollection.Add(theObject);
    }
}

Tutto ciò che è al di fuori delle parentesi graffe viene smaltito, quindi è fantastico smaltire i tuoi oggetti se non li usi.Questo perché se hai un oggetto SqlDataAdapter e lo usi solo una volta nel ciclo di vita dell'applicazione e stai riempiendo un solo set di dati e non ne hai più bisogno, puoi usare il codice:

using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
   // do stuff
} // here adapter_object is disposed automatically

L'istruzione using fornisce un meccanismo pratico per utilizzare correttamente gli oggetti IDisposable.Di norma, quando si utilizza un oggetto IDisposable, è necessario dichiararlo e istanziarlo in un'istruzione using.L'istruzione using chiama il metodo Dispose sull'oggetto nel modo corretto e (quando lo si utilizza come mostrato in precedenza) fa sì che l'oggetto stesso esca dall'ambito non appena viene chiamato Dispose.All'interno del blocco using, l'oggetto è di sola lettura e non può essere modificato o riassegnato.

Questo deriva da: Qui

Per me il nome "using" crea un po' di confusione, perché può essere una direttiva per importare uno spazio dei nomi o un'istruzione (come quella discussa qui) per la gestione degli errori.

Sarebbe stato carino un nome diverso per la gestione degli errori, e forse in qualche modo più ovvio.

Può anche essere utilizzato per creare ambiti, ad esempio:

class LoggerScope:IDisposable {
   static ThreadLocal<LoggerScope> threadScope = 
        new ThreadLocal<LoggerScope>();
   private LoggerScope previous;

   public static LoggerScope Current=> threadScope.Value;

   public bool WithTime{get;}

   public LoggerScope(bool withTime){
       previous = threadScope.Value;
       threadScope.Value = this;
       WithTime=withTime;
   }

   public void Dispose(){
       threadScope.Value = previous;
   }
}


class Program {
   public static void Main(params string[] args){
       new Program().Run();
   }

   public void Run(){
      log("something happend!");
      using(new LoggerScope(false)){
          log("the quick brown fox jumps over the lazy dog!");
          using(new LoggerScope(true)){
              log("nested scope!");
          }
      }
   }

   void log(string message){
      if(LoggerScope.Current!=null){
          Console.WriteLine(message);
          if(LoggerScope.Current.WithTime){
             Console.WriteLine(DateTime.Now);
          }
      }
   }

}

L'istruzione using indica a .NET di rilasciare l'oggetto specificato nel blocco using una volta che non è più necessario.Quindi dovresti usare il blocco 'using' per le classi che richiedono la pulizia dopo di loro, come i tipi System.IO.

Esistono due utilizzi dell'utilizzo della parola chiave in C# come segue.

  1. come direttiva

Generalmente utilizziamo la parola chiave using per aggiungere spazi dei nomi nei file code-behind e di classe.Quindi rende disponibili tutte le classi, interfacce e classi astratte, i relativi metodi e proprietà nella pagina corrente.

Ex:

using System.IO;  
  1. come una dichiarazione

Questo è un altro modo di utilizzare la parola chiave using in C#.Svolge un ruolo fondamentale nel migliorare le prestazioni nella Garbage Collection.L'istruzione using garantisce che Dispose() venga chiamato anche se si verifica un'eccezione durante la creazione di oggetti e la chiamata di metodi, proprietà e così via.Dispose() è un metodo presente nell'interfaccia IDisposable che aiuta a implementare la Garbage Collection personalizzata.In altre parole, se sto eseguendo alcune operazioni sul database (Inserisci, Aggiorna, Elimina) ma in qualche modo si verifica un'eccezione, qui l'istruzione using chiude automaticamente la connessione.Non è necessario chiamare esplicitamente il metodo Close() della connessione.

Un altro fattore importante è che aiuta nel pooling delle connessioni.Il pool di connessioni in .NET aiuta a eliminare la chiusura di una connessione al database più volte.Invia l'oggetto connessione a un pool per uso futuro (prossima chiamata al database).La prossima volta che viene richiamata una connessione al database dall'applicazione, il pool di connessioni recupera gli oggetti disponibili nel pool.Quindi aiuta a migliorare le prestazioni dell'applicazione.Pertanto, quando utilizziamo l'istruzione using, il controller invia automaticamente l'oggetto al pool di connessioni, non è necessario chiamare esplicitamente i metodi Close() e Dispose().

Puoi fare lo stesso di ciò che sta facendo l'istruzione using usando il blocco try-catch e chiamando esplicitamente Dispose() all'interno del blocco last.Ma l'istruzione using esegue automaticamente le chiamate per rendere il codice più pulito ed elegante.All'interno del blocco using, l'oggetto è di sola lettura e non può essere modificato o riassegnato.

Ex:

    string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";  

using (SqlConnection conn = new SqlConnection(connString))  
{  
      SqlCommand cmd = conn.CreateCommand();  
      cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";  
      conn.Open();  
      using (SqlDataReader dr = cmd.ExecuteReader())  
      {  
         while (dr.Read())  
         Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));  
      }  
}  

Nel codice precedente non chiudo alcuna connessione, si chiuderà automaticamente.L'istruzione using chiamerà conn.Close() automaticamente a causa dell'istruzione using (using (SqlConnection conn = new SqlConnection(connString)) e lo stesso per un oggetto SqlDataReader.Inoltre, se si verifica un'eccezione, la connessione verrà chiusa automaticamente.

Per maggiori informazioni --> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-using-in-C-Sharp472/

L'uso come istruzione chiama automaticamente lo smalto sull'oggetto specificato.L'oggetto deve implementare l'interfaccia IDisposable.È possibile utilizzare diversi oggetti in una dichiarazione purché siano dello stesso tipo.

Il CLR converte il tuo codice in MSIL.E l'istruzione using viene tradotta in un tentativo e infine blocca.Questo è il modo in cui l'istruzione using è rappresentata in IL.Un'istruzione using è tradotta in tre parti:acquisizione, utilizzo e smaltimento.La risorsa viene prima acquisita, quindi l'utilizzo viene racchiuso in un'istruzione try con una clausola final.L'oggetto viene quindi eliminato nella clausola final.

La clausola Using viene utilizzata per definire l'ambito per la variabile particolare.Per esempio:

     Using(SqlConnection conn=new SqlConnection(ConnectionString)
            {
                Conn.Open()
            // Execute sql statements here.
           // You do not have to close the connection explicitly here as "USING" will close the connection once the object Conn becomes out of the defined scope.
            }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top