it-swarm-tr.com

C # ile "using" kullanımları nelerdir

Kullanıcı kokos harika C # Gizli Özellikleri sorusunu using anahtar sözcüğünü kullanarak cevapladı. Bunu açıklayabilir misiniz? using kullanımları nelerdir?

295
ubermonkey

using ifadesinin nedeni, nesnenin kapsam dışına çıkar çıkmaz elden çıkarılmasını sağlamak ve bunun olmasını sağlamak için açık kod gerektirmemesidir.

C # içindeki 'using' ifadesini anlama, .NET CLR dönüştürür

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

için

{ // 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

Pek çok insan hala yapıyor:

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

Sanırım birçok insan hala yapabileceğini bilmiyor:

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

Böyle şeyler:

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

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

Bu SqlConnection, .Close() işlevini açıkça çağırmaya gerek kalmadan kapatılır ve bu, bir istisna atılsa bile , try/catch/finally gerekmeden gerçekleşir.

96
Joel Coehoorn

iDisposable aramak için kullanılabilir. Ayrıca takma ad türlerinde de kullanılabilir.

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

anlamında kullanma

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

Aslında bir deneme/nihayet blok için stenodur. Bu kod eşdeğerdir:

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

Elbette, ilk snippet'in ikinciden çok daha öz olduğunu ve ayrıca bir istisna atılsa bile temizleme yapmak isteyebileceğiniz birçok türde şeyin olduğunu not edersiniz. Bu nedenle, Dispose yönteminde rasgele kod yürütmenize izin veren Scope olarak adlandırdığımız bir sınıf bulduk. Örneğin, bir işlemi gerçekleştirmeye çalıştıktan sonra her zaman false olarak ayarlamak istediğiniz IsWorking adlı bir özelliğiniz varsa, şöyle yapardınız:

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

Çözümümüz ve nasıl elde ettiğimiz hakkında daha fazla bilgi edinebilirsiniz burada .

21
David Mitchell

Microsoft belgeleri ( kullanarak çift işlevine sahiptir ( https: //msdn.Microsoft.com/en-us/library/) zhdeatwt.aspx ), hem yönergesi ve hem de cümleleri . Bir ifadesi olarak , burada diğer cevaplarda da belirtildiği gibi, anahtar kelime temelde bir kullanım için bir kapsam belirlemek üzere sözdizimsel bir şekerdir nesnesi. Bir yönergesi olarak, ad alanlarını ve türlerini içe aktarmak için düzenli olarak kullanılır. Ayrıca bir direktif olarak, "C # 5.0 Özetle: Tanımlayıcı Kılavuzda" kitabında belirtildiği gibi, ad alanları ve türleri için takma adlar oluşturabilirsiniz ( http://www.Amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8 ), Joseph ve Ben Albahari tarafından. Bir örnek:

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

Bu, akıllıca benimsenmesi gereken bir şeydir, çünkü bu uygulamanın kötüye kullanılması birinin kodunun açıklığına zarar verebilir. DotNetPearls'da C # takma adları hakkında, artı ve eksilerden bahseden Güzel bir açıklama var ( http: //www.dotnetperls.com/using-alias ).

10

Geçmişte girdi ve çıktı akışlarıyla çalışmak için çok kullandım. Onları güzel bir şekilde yuvalayabilirsiniz ve genellikle karşılaştığınız olası sorunların çoğunu ortadan kaldırır (otomatik olarak imha çağrısı yaparak). Örneğin:

        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

Sadece şaşırdığım bir şey eklemek gelmedi. Kullanmanın en ilginç özelliği (benim görüşüme göre), kullanım bloğundan nasıl çıkacağınıza dair hiçbir şey olmaması, nesneyi her zaman elden çıkarmasıdır. Buna iade ve istisnalar dahildir.

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

İstisna atıldığında veya listenin döndürüldüğü önemli değildir. DbContext nesnesi her zaman atılacak.

8
Pluc

Kullanmanın bir diğer harika kullanımı, kalıcı bir iletişim kutusunu başlatırken.

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using
6
Lucas

Diğer ad ad alanını aşağıdaki örnekle kullanabilirsiniz:

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

Buna bir takma ad yönergesini kullanma görebileceğiniz gibi denir, kodunuzda neye başvurduğunuzu açıkça belirtmek istiyorsanız uzun soluklu referansları gizlemek için kullanılabilir.

LegacyEntities.Account

onun yerine

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

ya da sadece

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

Sonuç olarak, IDisposable, her zaman uygulayan bir tür yerel değişken kullandığınızda, istisnasız, using kullanın1.

Yerel olmayan IDisposable değişkenini kullanırsanız, o zaman her zaman IDisposable pattern uygulayın.

İki basit kural, istisna yok1. Kaynak sızıntılarını önlemek aksi takdirde * lerde gerçek bir acıdır.


1): Tek istisna - istisnaları ele alırken. Daha sonra, Dispose bloğunda açıkça finally çağrısı yapmak daha az kod olabilir.

5
Konrad Rudolph

İlginçtir, başka ilginç şeyler için use/IDisposable şablonunu da kullanabilirsiniz (Rhino Mocks'ın kullandığı diğer nokta gibi). Temel olarak, derleyicinin her zaman çağıracağı gerçeğinden yararlanabilirsiniz. "Kullanılan" nesneyi kullanın. Belirli bir işlemden sonra olması gereken bir şeyiniz varsa ... kesin bir başlangıcı ve sonu olan bir şey varsa ... o zaman işlemi yapıcıda başlatan tanımlanabilir bir sınıf oluşturabilir ve daha sonra Dispose yönteminde bitirebilirsiniz.

Bu, söz konusu işlemin açık başlangıcını ve sonunu belirtmek için gerçekten Nice'i sözdizimi kullanarak kullanmanızı sağlar. Bu ayrıca System.Transactions sayfalarının nasıl çalıştığıdır.

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

ADO.NET'i kullanırken, keywork'ü bağlantı nesneniz veya okuyucu nesneniz gibi şeyler için kullanabilirsiniz. Bu şekilde kod bloğu tamamlandığında bağlantınız otomatik olarak elden çıkar.

3
Joseph Daigle

"alan", ad alanı çakışmalarını çözmek için de kullanılabilir. Konuyla ilgili kısa bir ders için http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ bakınız.

3
David Arno

sing, kullanıldıktan sonra elden çıkarmak istediğiniz bir kaynağa sahipseniz kullanılır.

Örneğin, bir Dosya kaynağı tahsis ediyorsanız ve küçük bir okuma veya yazma için kodun bir bölümünde kullanmanız gerekiyorsa, kullanımı, en kısa sürede dosya kaynağının atılması için yararlıdır.

Kullanılan kaynağın düzgün çalışması için IDEposable uygulaması gerekiyor.

Örnek:

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

Using ifadesi, .NET'e, artık gerekli olmadığında kullanım bloğunda belirtilen nesneyi serbest bırakmasını söyler. Bu nedenle, System.IO Çeşitleri gibi, onlardan sonra temizlenmesi gereken sınıflar için 'using' bloğunu kullanmalısınız.

1

Anahtar kelimeyi C # ile aşağıdaki gibi kullanmanın iki yolu vardır.

  1. bir direktif olarak

Genel olarak, kod kodunun arkasına ve sınıf dosyalarına ad alanları eklemek için using anahtar sözcüğünü kullanırız. Daha sonra, mevcut sayfadaki tüm sınıfları, arayüzleri ve soyut sınıfları ve bunların yöntem ve özelliklerini kullanılabilir hale getirir.

Ör:

using System.IO;  
  1. ifade olarak

Bu, C # anahtar sözcüğünü kullanmanın başka bir yoludur. Çöp Toplama'daki performansın iyileştirilmesinde hayati bir rol oynar. Using ifadesi, nesneleri oluştururken ve yöntemleri, özellikleri vb. Çağırırken bir istisna olsa bile Dispose () yönteminin çağrılmasını sağlar. Dispose (), özel Çöp Toplama'nın uygulanmasına yardımcı olan Tanımlanabilir arabirimde bulunan bir yöntemdir. Başka bir deyişle, bazı veritabanı işlemleri yapıyorum (Ekle, Güncelle, Sil), ancak bir şekilde bir istisna meydana gelirse, burada use ifadesi bağlantıyı otomatik olarak kapatır. Açıkça bağlantı Close () yöntemini çağırmanıza gerek yok.

Diğer önemli bir faktör de Bağlantı Havuzunda yardımcı olmasıdır. .NET'teki Bağlantı Havuzu, bir veritabanı bağlantısının birçok kez kapatılmasını önlemeye yardımcı olur. Bağlantı nesnesini ileride kullanmak üzere bir havuza gönderir (sonraki veritabanı çağrısı). Uygulamanızdan bir sonraki sefer veritabanı bağlantısı çağrıldığında, bağlantı havuzu havuzdaki mevcut nesneleri alır. Bu nedenle uygulamanın performansını arttırmaya yardımcı olur. Bu nedenle, use ifadesini kullandığımızda, denetleyici nesneyi otomatik olarak bağlantı havuzuna gönderir, Close () ve Dispose () yöntemlerini açıkça çağırmaya gerek yoktur.

Try-catch bloğunu kullanarak using ifadesinin yaptığı ile aynı şeyi yapabilir ve en sonunda bloğun içindeki Dispose () yöntemini çağırabilirsiniz. Ancak using ifadesi kodu daha temiz ve şık hale getirmek için aramaları otomatik olarak yapar. Use bloğu içerisinde nesne salt okunurdur ve değiştirilemez veya yeniden atanamaz.

Ör:

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

Yukarıdaki kodda herhangi bir bağlantıyı kapatmıyorum, otomatik olarak kapanacak. Using ifadesi, use ifadesi nedeniyle otomatik olarak conn.Close () öğesini çağırır (use (SqlConnection conn = new SqlConnection (connString)) ve SqlDataReader nesnesi için aynıdır. Ayrıca bir istisna olursa bağlantıyı otomatik olarak kapatır.

Daha fazla bilgi için -> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-using-in-C-Sharp472/

1

Benim için "using" ismi biraz kafa karıştırıcı, çünkü hata işleme için bir Namespace veya bir ifade (burada tartışılan gibi) almak için bir yönerge olabilir.

Hata işlemesi için farklı bir ad Güzel olurdu ve belki de bir şekilde daha belirgindi.

1
Seb

Ayrıca, Örnek için kapsam oluşturmak için de kullanılabilir:

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

Çok önemli değil, ancak kullanımı anında kaynakları değiştirmek için de kullanılabilir. Evet, daha önce de belirtildiği gibi atılabilir, ancak belki de özellikle uygulamanızın geri kalanında diğer kaynaklarla uyuşmayan kaynakları istemezsiniz. Öyleyse elden çıkarmak istiyorsun, böylece başka bir yere karışmaz.

1
Scot McPherson

Rhino Mocks Record-playback sözdizimi , using cihazını ilginç bir şekilde kullanır.

1
Gilligan

Using ifadesi, IDisposable nesnelerini doğru kullanmak için kolaylık mekanizması sağlar. Kural olarak, IDisposable bir nesne kullandığınızda, bunu bir using ifadesinde bildirmeli ve başlatmalısınız. Using ifadesi, nesnede Dispose yöntemini doğru şekilde çağırır ve (daha önce gösterildiği gibi kullandığınızda), Dispose'ın çağrıldığı anda nesnenin kapsam dışına çıkmasına neden olur. Use bloğu içerisinde nesne salt okunurdur ve değiştirilemez veya yeniden atanamaz.

Bu geliyor: burada

1
snowell

Aşağıdaki yorumlar sayesinde bu yazıyı biraz temizleyeceğim (özür dilerken 'çöp toplama' kelimesini kullanmamalıydım):
Kullanırken, kullanımın kapsamının sonundaki nesnede Dispose () yöntemini çağırır. Böylece Dispose () metodunuzda bir miktar harika temizleme kodu bulunabilir.
Umarım bu işaretlemeyi kaldırabileceklerini umduğum bir mermi noktası: Kullanılabilirliği uygularsanız, Dispose () uygulamanızda GC.SuppressFinalize () öğesini çağırdığınızdan emin olun, aksi halde otomatik çöp toplama işlemi beraberinde gelir. ve bir noktada Sonlandırın, eğer en azından Dispose () yöntemini kullandıysanız, en azından kaynak israfı olur.

1
Grank

Kıvrımlı parantez dışındaki her şey elden çıkarılmıştır, bu yüzden kullanmıyorsanız nesnelerinizi elden çıkarmak mükemmeldir. Bunun nedeni bir SqlDataAdapter nesnesine sahipseniz ve bunu uygulama yaşam döngüsünde yalnızca bir kez kullanıyorsanız ve yalnızca bir veri kümesini dolduruyorsanız ve artık ihtiyacınız kalmadıysa, kodu kullanabilirsiniz:

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

Using anahtar sözcüğü, nesnenin kapsamını tanımlar ve kapsam tamamlandığında nesneyi elden çıkarır. Örneğin.

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

Anahtar kelimeyi kullanarak C # ile ilgili MSDN makalesi için burada bölümüne bakın.

1
David Basarab

Nesnenin derhal atıldığı makul kullanımın bir başka örneği:

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
Brendan Kendrick