it-swarm-eu.dev

Was sind die Verwendungen von "using" in C #

User kokos hat die wunderbare Frage Hidden Features of C # unter Erwähnung des Schlüsselworts using beantwortet. Können Sie das näher erläutern? Was sind die Verwendungen von using?

295
ubermonkey

Der Grund für die Anweisung using besteht darin, sicherzustellen, dass das Objekt entsorgt wird, sobald es den Gültigkeitsbereich verlässt, und dass kein expliziter Code erforderlich ist, um dies sicherzustellen.

Wie in Verstehen der using-Anweisung in C # wird die .NET-CLR konvertiert

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

zu

{ // 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();
    }
}
446
paulwhit

Da viele Leute immer noch tun:

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

Ich denke, viele Leute wissen immer noch nicht, dass Sie das können:

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

Dinge wie dieses:

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

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

Dieses SqlConnection wird geschlossen, ohne dass die Funktion .Close() explizit aufgerufen werden muss. Dies geschieht auch wenn eine Ausnahme ausgelöst wird, ohne dass ein try/catch/finally.

96
Joel Coehoorn

using kann verwendet werden, um IDisposable aufzurufen. Es können auch Alias-Typen verwendet werden.

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

verwendung im Sinne von

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

Ist eigentlich eine Abkürzung für einen Versuch/Endlich Block. Es entspricht dem Code:

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

Sie werden natürlich bemerken, dass das erste Snippet viel prägnanter ist als das zweite und dass es viele Arten von Dingen gibt, die Sie möglicherweise als Bereinigung durchführen möchten, selbst wenn eine Ausnahme ausgelöst wird. Aus diesem Grund haben wir eine Klasse namens Scope entwickelt, mit der Sie beliebigen Code in der Dispose-Methode ausführen können. Wenn Sie beispielsweise eine Eigenschaft namens IsWorking hatten, die Sie nach dem Versuch, eine Operation auszuführen, immer auf false setzen wollten, würden Sie dies folgendermaßen tun:

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

Lesen Sie mehr über unsere Lösung und wie wir sie abgeleitet haben hier .

21
David Mitchell

Microsoft-Dokumentation besagt, dass mit eine Doppelfunktion hat ( https://msdn.Microsoft.com/en-us/library/zhdeatwt.aspx ), sowohl als Direktive als auch in Anweisungen. Als Anweisung, wie hier in anderen Antworten ausgeführt, ist das Schlüsselwort im Grunde syntaktischer Zucker, um einen Bereich zum Entsorgen eines IDisposable -Objekts zu bestimmen . Als Direktive wird es routinemäßig zum Importieren von Namespaces und Typen verwendet. Sie können auch als Direktive Aliase für Namespaces und Typen erstellen, wie in dem Buch "C # 5.0 Kurz zusammengefasst: Das endgültige Handbuch" ( http: // www .Amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8 ), von Joseph und Ben Albahari. Ein Beispiel:

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;
        }
    }
}

Dies sollte mit Bedacht gewählt werden, da der Missbrauch dieser Praxis die Klarheit des eigenen Codes beeinträchtigen kann. In DotNetPearls ( http://www.dotnetperls.com/using-alias ) gibt es eine nette Erklärung zu C # -Aliasen, in der auch Vor- und Nachteile erwähnt werden.

10

Ich habe es in der Vergangenheit oft verwendet, um mit Eingabe- und Ausgabestreams zu arbeiten. Sie können sie gut verschachteln und viele der potenziellen Probleme, auf die Sie normalerweise stoßen, werden dadurch beseitigt (indem Sie automatisch dispose aufrufen). Zum Beispiel:

        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();
                }
            }
        }
10
Sam Schutte

Nur etwas hinzuzufügen, das mich überraschte, kam nicht auf. Das interessanteste Merkmal von using (meiner Meinung nach) ist, dass unabhängig davon, wie Sie den using-Block verlassen, das Objekt immer entsorgt wird. Dies schließt Rückgaben und Ausnahmen ein.

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

Es spielt keine Rolle, ob die Ausnahme ausgelöst oder die Liste zurückgegeben wird. Das DbContext-Objekt wird immer freigegeben.

8
Pluc

Eine weitere nützliche Funktion ist das Instanziieren eines modalen Dialogfelds.

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using
6
Lucas

Sie können den Alias-Namespace anhand des folgenden Beispiels verwenden:

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

Dies wird als nter Verwendung einer Alias-Direktive bezeichnet. Wie Sie sehen, kann es verwendet werden, um langatmige Verweise auszublenden, wenn Sie in Ihrem Code deutlich machen möchten, auf was Sie sich beispielsweise beziehen.

LegacyEntities.Account

anstatt von

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

oder einfach

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

Wenn Sie also eine lokale Variable eines Typs verwenden, der IDisposable implementiert, verwenden Sie ausnahmslos immer using1.

Wenn Sie nicht-lokale IDisposable Variablen verwenden, implementieren Sie immer das IDisposable Muster .

Zwei einfache Regeln, keine Ausnahme1. Das Vermeiden von Ressourcenlecks ansonsten ist ein echtes Problem.


1): Die einzige Ausnahme ist - wenn Sie Ausnahmen behandeln. Es könnte dann weniger Code sein, um Dispose explizit im finally -Block aufzurufen.

5
Konrad Rudolph

Interessanterweise können Sie das using/IDisposable-Muster auch für andere interessante Dinge verwenden (z. B. für den anderen Verwendungszweck von Rhino Mocks). Grundsätzlich können Sie die Tatsache ausnutzen, dass der Compiler immer aufruft. Wenn nach einer bestimmten Operation etwas geschehen muss, das einen bestimmten Anfang und ein bestimmtes Ende hat, können Sie einfach eine IDisposable-Klasse erstellen, die die Operation im Konstruktor startet und dann mit der Dispose-Methode endet.

Auf diese Weise können Sie die Syntax "Real Nice using" verwenden, um den expliziten Beginn und das explizite Ende dieser Operation anzugeben. So funktioniert auch das System.Transactions-Zeug.

4
Joel Martinez
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 
            }
    }
3
Shiraj Momin

Wenn Sie ADO.NET verwenden, können Sie die Schlüssel für Dinge wie Ihr Verbindungsobjekt oder Ihr Leseobjekt verwenden. Auf diese Weise wird Ihre Verbindung nach Abschluss des Codeblocks automatisch getrennt.

3
Joseph Daigle

"using" kann auch zum Auflösen von Namensraumkonflikten verwendet werden. Siehe http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ für ein kurzes Tutorial, das ich zu diesem Thema geschrieben habe.

3
David Arno

sing wird verwendet, wenn Sie eine Ressource haben, die Sie entsorgen möchten, nachdem sie verwendet wurde.

Wenn Sie beispielsweise eine Dateiressource zuweisen und diese nur in einem Codeabschnitt zum Lesen oder Schreiben verwenden müssen, ist die Verwendung hilfreich, um die Dateiressource zu entsorgen, sobald Sie fertig sind.

Die verwendete Ressource muss IDisposable implementieren, um ordnungsgemäß zu funktionieren.

Beispiel:

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

Die using-Anweisung weist .NET an, das im using-Block angegebene Objekt freizugeben, sobald es nicht mehr benötigt wird. Daher sollten Sie den 'using'-Block für Klassen verwenden, nach denen eine Bereinigung erforderlich ist, z. B. System.IO Types.

1

Es gibt zwei Verwendungsmöglichkeiten von Schlüsselwörtern in C #:.

  1. als Richtlinie

Im Allgemeinen verwenden wir das Schlüsselwort using, um Namespaces in CodeBehind- und Klassendateien hinzuzufügen. Anschließend werden alle Klassen, Interfaces und abstrakten Klassen sowie deren Methoden und Eigenschaften auf der aktuellen Seite verfügbar gemacht.

Ex:

using System.IO;  
  1. als Aussage

Dies ist eine weitere Möglichkeit, das using-Schlüsselwort in C # zu verwenden. Es spielt eine wichtige Rolle bei der Verbesserung der Leistung in der Garbage Collection. Die using-Anweisung stellt sicher, dass Dispose () aufgerufen wird, auch wenn beim Erstellen von Objekten und Aufrufen von Methoden, Eigenschaften usw. eine Ausnahme auftritt. Dispose () ist eine Methode, die in der IDisposable-Schnittstelle vorhanden ist, mit deren Hilfe die benutzerdefinierte Garbage Collection implementiert werden kann. Mit anderen Worten, wenn ich eine Datenbankoperation durchführe (Einfügen, Aktualisieren, Löschen), aber irgendwie eine Ausnahme auftritt, wird die Verbindung hier durch die using-Anweisung automatisch geschlossen. Die Methode close () der Verbindung muss nicht explizit aufgerufen werden.

Ein weiterer wichtiger Faktor ist, dass er beim Verbindungspooling hilft. Mit dem Verbindungspooling in .NET können Sie das mehrfache Schließen einer Datenbankverbindung verhindern. Es sendet das Verbindungsobjekt zur zukünftigen Verwendung (nächster Datenbankaufruf) an einen Pool. Beim nächsten Aufruf einer Datenbankverbindung aus Ihrer Anwendung ruft der Verbindungspool die im Pool verfügbaren Objekte ab. Es hilft also, die Leistung der Anwendung zu verbessern. Wenn wir also die using-Anweisung verwenden, sendet der Controller das Objekt automatisch an den Verbindungspool, sodass die Methoden Close () und Dispose () nicht explizit aufgerufen werden müssen.

Sie können dasselbe tun wie in der using-Anweisung, indem Sie den try-catch-Block verwenden und das Dispose () innerhalb des finally-Blocks explizit aufrufen. Die using-Anweisung führt die Aufrufe jedoch automatisch aus, um den Code sauberer und eleganter zu gestalten. Innerhalb des using-Blocks ist das Objekt schreibgeschützt und kann nicht geändert oder neu zugewiesen werden.

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));  
      }  
}  

Im vorhergehenden Code schließe ich keine Verbindung, es wird automatisch geschlossen. Die using-Anweisung ruft conn.Close () automatisch auf, da die using-Anweisung (using (SqlConnection conn = new SqlConnection (connString)) für ein SqlDataReader-Objekt verwendet wird. Außerdem wird die Verbindung automatisch geschlossen, wenn eine Ausnahme auftritt.

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

1

Für mich ist der Name "using" etwas verwirrend, da es sich um eine Direktive zum Importieren eines Namespace oder einer Anweisung (wie hier beschrieben) zur Fehlerbehandlung handeln kann.

Ein anderer Name für die Fehlerbehandlung wäre Nice gewesen, und vielleicht ein etwas offensichtlicherer.

1
Seb

Es kann auch zum Erstellen von Gültigkeitsbereichen verwendet werden. Beispiel:

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);
          }
      }
   }

}
1
Siamand

Nicht, dass es extrem wichtig wäre, aber mithilfe von können Ressourcen auch im laufenden Betrieb geändert werden. Ja, verfügbar, wie bereits erwähnt, aber möglicherweise möchten Sie nicht, dass die Ressourcen während der restlichen Ausführung nicht mit den anderen Ressourcen übereinstimmen. Sie möchten es also entsorgen, damit es nicht anderweitig stört.

1
Scot McPherson

Die Rhino Mocks Record-Playback-Syntax verwendet using auf interessante Weise.

1
Gilligan

Die using-Anweisung bietet einen praktischen Mechanismus zur korrekten Verwendung von IDisposable-Objekten. Wenn Sie ein IDisposable-Objekt verwenden, sollten Sie es in der Regel in einer using-Anweisung deklarieren und instanziieren. Die using-Anweisung ruft die Dispose-Methode für das Objekt auf die richtige Weise auf und bewirkt (bei Verwendung wie oben gezeigt), dass das Objekt selbst den Gültigkeitsbereich verlässt, sobald Dispose aufgerufen wird. Innerhalb des using-Blocks ist das Objekt schreibgeschützt und kann nicht geändert oder neu zugewiesen werden.

Dies kommt von: hier

1
snowell

Dank den Kommentaren unten werde ich diesen Beitrag ein wenig bereinigen (ich hätte die Wörter "Garbage Collection" zu der Zeit nicht verwenden sollen, entschuldige mich):
Wenn Sie using verwenden, wird die Dispose () -Methode für das Objekt am Ende des Gültigkeitsbereichs der using aufgerufen. Sie können also in Ihrer Dispose () -Methode eine ganze Menge großartigen Bereinigungscodes verwenden.
Ein Bullet Point, der hoffentlich dieses Unmarkeddown bekommen wird: Wenn Sie IDisposable implementieren, stellen Sie sicher, dass Sie GC.SuppressFinalize () in Ihrer Dispose () -Implementierung aufrufen, da andernfalls die automatische Garbage Collection versuchen wird, mitzukommen und Finalisieren Sie es irgendwann, was zumindest eine Verschwendung von Ressourcen wäre, wenn Sie bereits Dispose () d davon haben.

1
Grank

Alles, was sich außerhalb der geschweiften Klammern befindet, wird entsorgt. Daher ist es hilfreich, Ihre Objekte zu entsorgen, wenn Sie sie nicht verwenden. Dies liegt daran, dass Sie den folgenden Code verwenden können, wenn Sie ein SqlDataAdapter-Objekt haben und es nur einmal im Anwendungslebenszyklus verwenden und nur einen Datensatz ausfüllen und ihn nicht mehr benötigen:

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

Das using-Schlüsselwort definiert den Bereich für das Objekt und entsorgt das Objekt, wenn der Bereich vollständig ist. Zum Beispiel.

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

Siehe hier für den MSDN-Artikel zum Schlüsselwort C # using.

1
David Basarab

Ein weiteres Beispiel für eine sinnvolle Verwendung, bei der das Objekt sofort entsorgt wird:

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);
    }
}
1