การใช้“ การใช้” ใน C # คืออะไร


319

ผู้ใช้kokosตอบคุณสมบัติที่ซ่อนอยู่ที่ยอดเยี่ยมของคำถามC #โดยกล่าวถึงusingคำหลัก คุณอธิบายรายละเอียดเกี่ยวกับเรื่องนั้นได้ไหม? มีประโยชน์usingอะไรบ้าง?


มันเป็นวิธีการสนับสนุน C # ของ RAII สำนวน: hackcraft.net/raii
Nemanja Trifunovic

1
คุณสามารถใช้สำหรับวัตถุที่มีการใช้งานอินเตอร์เฟซ IDispose การใช้จะเรียกวิธีการกำจัดเมื่อวัตถุนั้นออกนอกขอบเขต มันรับประกันว่าจะโทรออกแม้ว่าจะมีข้อยกเว้นเกิดขึ้น มันทำงานเหมือนประโยคสุดท้ายและดำเนินการกำจัด
CharithJ

คำตอบ:


480

เหตุผลสำหรับusingคำสั่งคือเพื่อให้แน่ใจว่าวัตถุถูกกำจัดทันทีที่มันพ้นขอบเขตและไม่จำเป็นต้องใช้รหัสที่ชัดเจนเพื่อให้แน่ใจว่าสิ่งนี้เกิดขึ้น

เช่นเดียวกับในการทำความเข้าใจคำสั่ง 'using' ใน C # (codeproject)และการใช้ออบเจ็กต์ที่ใช้ IDisposable (microsoft)คอมไพเลอร์ C # จะทำการแปลง

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

ถึง

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

C # 8 แนะนำไวยากรณ์ใหม่ชื่อ " using declarations ":

การประกาศการใช้เป็นการประกาศตัวแปรที่นำหน้าด้วยคีย์เวิร์ดการใช้ มันบอกคอมไพเลอร์ว่าตัวแปรที่ประกาศควรถูกกำจัดในตอนท้ายของขอบเขตล้อมรอบ

ดังนั้นรหัสเทียบเท่าข้างต้นจะเป็น:

using var myRes = new MyResource();
myRes.DoSomething();

และเมื่อการควบคุมออกจากขอบเขตที่มีอยู่ (โดยปกติจะเป็นวิธีการ แต่มันก็สามารถบล็อกรหัส) myResจะถูกกำจัด


129
โปรดทราบว่ามันไม่จำเป็นต้องเป็นเรื่องของวัตถุที่ถูกกำจัดอย่างถูกต้องแต่ส่วนใหญ่ของมันจะถูกกำจัดในเวลาที่เหมาะสม วัตถุที่ใช้งาน IDisposable ซึ่งยึดครองทรัพยากรที่ไม่มีการจัดการเช่นลำธารและตัวจัดการไฟล์จะใช้เครื่องมือตัวสุดท้ายที่จะทำให้แน่ใจว่า Dispose ถูกเรียกใช้ในระหว่างการรวบรวมขยะ ปัญหาคือ GC อาจไม่เกิดขึ้นเป็นเวลานาน usingทำให้แน่ใจว่าDisposeมีการเรียกใช้เมื่อคุณผ่านวัตถุ
จอห์นแซนเดอร์

1
โปรดทราบว่ารหัสที่สร้างขึ้นจะแตกต่างกันเล็กน้อยเมื่อMyRessourceเป็นโครงสร้าง นอกจากนี้เห็นได้ชัดว่าการทดสอบเป็นโมฆะไม่มี IDisposableแต่ยังไม่มีมวย การโทรเสมือนที่ถูก จำกัด ถูกปล่อยออกมา
Romain Verdier

4
ทำไมไม่มีใครพูดถึงว่าการใช้จะใช้เพื่อนำเข้าเนมสเปซด้วย?
Kyle Delaney

3
โปรดทราบว่าหากคุณเขียนโค้ดเวอร์ชันที่สองโดยตรงผลลัพธ์จะไม่เหมือนกัน หากคุณใช้usingตัวแปรภายในจะเป็นแบบอ่านอย่างเดียว ไม่มีทางที่จะบรรลุถึงสิ่งนี้สำหรับตัวแปรท้องถิ่นโดยไม่ต้องมีusingคำสั่ง
Massimiliano Kraus

1
@JohnSaunders นอกจากนี้ยังไม่รับประกันว่าจะใช้ตัวเลือกสุดท้าย
Pablo H

124

เนื่องจากผู้คนจำนวนมากยังคงทำ:

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

ฉันเดาว่าหลายคนยังไม่รู้ว่าคุณสามารถทำได้:

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

2
เป็นไปได้หรือไม่ที่จะใช้วัตถุหลายประเภทที่แตกต่างกันในการใช้คำสั่งเดียว?
Agnel Kurian

12
@AgnelKurian ไม่: "ข้อผิดพลาด CS1044: ไม่สามารถใช้มากกว่าหนึ่งประเภทในคำสั่ง for, ใช้, แก้ไขหรือประกาศ"
David Sykes

10
คำถามนี้จะตอบคำถามได้อย่างไร
เลียม

จริง ๆ แล้วฉันไม่รู้ว่าฉันสามารถเขียนสองรายการโดยใช้ statemens ก่อนบล็อกรหัสเดียว (จะซ้อนพวกเขาทุกครั้ง)
kub1x

97

สิ่งนี้:

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

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

นี้SqlConnectionจะปิดให้บริการโดยไม่จำเป็นต้องชัดเจนเรียก.Close()ฟังก์ชั่นและสิ่งนี้จะเกิดขึ้นแม้ว่ายกเว้นจะโยนโดยไม่จำเป็นต้องเป็นtry/ /catchfinally


1
จะทำอย่างไรถ้าฉันใช้ "การใช้" ภายในเมธอดและฉันกลับมาในระหว่างการใช้งาน มีปัญหาอะไรไหม?
francisco_ssb

1
ไม่มีปัญหา ในตัวอย่างที่นี่การเชื่อมต่อจะยังคงปิดแม้ว่าคุณจะreturnอยู่ตรงกลางของusingบล็อก
Joel Coehoorn

30

ใช้สามารถใช้โทร IDisposable นอกจากนี้ยังสามารถใช้กับประเภทนามแฝง

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

21

ใช้ในแง่ของ

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

เป็นชวเลขจริงๆสำหรับการลอง / ปิดกั้นในที่สุด มันเทียบเท่ากับรหัส:

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

คุณจะทราบได้ว่าตัวอย่างข้อมูลแรกนั้นมีความกระชับมากกว่าชุดที่สองและมีหลายสิ่งหลายอย่างที่คุณอาจต้องการทำเป็นล้างข้อมูลแม้ว่าจะมีข้อยกเว้นเกิดขึ้นก็ตาม ด้วยเหตุนี้เราจึงมาพร้อมกับคลาสที่เราเรียกว่า Scope ที่ให้คุณรันโค้ดโดยพลการในวิธีการกำจัด ตัวอย่างเช่นหากคุณมีคุณสมบัติชื่อ IsWorking ที่คุณต้องการตั้งค่าเป็นเท็จหลังจากพยายามทำการดำเนินการคุณจะต้องทำสิ่งนี้:

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

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับโซลูชั่นของเราและวิธีการที่เราได้รับมามันนี่


12

รัฐเอกสาร Microsoft ที่ใช้มีฟังก์ชั่นคู่ ( https://msdn.microsoft.com/en-us/library/zhdeatwt.aspx ) ทั้งสองเป็นคำสั่งและในงบ ตามที่ระบุไว้ในคำตอบอื่น ๆ คำหลักนั้นเป็นน้ำตาลทรายประโยคเพื่อกำหนดขอบเขตในการกำจัดวัตถุIDisposable เป็นคำสั่งมันถูกใช้เป็นประจำเพื่อนำเข้าเนมสเปซและประเภท นอกจากนี้คุณยังสามารถสร้างนามแฝงสำหรับเนมสเปซและประเภทตามที่ระบุไว้ในหนังสือ "C # 5.0 โดยสรุป: คู่มือสรุป" ( http://www.amazon.com/5-0-Nutshell-The- แตกหักอ้างอิง-ebook / DP / B008E6I1K8) โดย Joseph และ Ben Albahari ตัวอย่างหนึ่ง:

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

นี่คือสิ่งที่จะนำมาใช้อย่างชาญฉลาดเนื่องจากการละเมิดของการปฏิบัตินี้สามารถทำร้ายความชัดเจนของรหัสของคน มีคำอธิบายที่ดีเกี่ยวกับนามแฝง C # เช่นกันที่กล่าวถึงข้อดีและข้อเสียใน DotNetPearls ( http://www.dotnetperls.com/using-alias )


4
ไม่โกหก: ฉันเกลียดการใช้usingเป็นเครื่องมือนามแฝง มันทำให้ฉันสับสนเมื่ออ่านรหัส - ฉันรู้แล้วว่าSystem.Collectionsมีอยู่และมีIEnumerable<T>คลาส การใช้นามแฝงเรียกมันอย่างอื่นทำให้ฉันงงสำหรับฉัน ฉันเห็นusing FooCollection = IEnumerable<Foo>วิธีที่จะทำให้นักพัฒนาในภายหลังอ่านโค้ดและคิดว่า "นรกคืออะไรFooCollectionและทำไมจึงไม่มีคลาสสำหรับที่แห่งนี้" ฉันไม่เคยใช้มันและจะกีดกันการใช้งาน แต่นั่นอาจเป็นฉัน
Ari Roth

1
ภาคผนวก: ฉันจะยอมรับว่าอาจมีการใช้งานเป็นครั้งคราวเช่นในตัวอย่างของคุณที่คุณใช้เพื่อกำหนดผู้รับมอบสิทธิ์ แต่ฉันก็เถียงว่ามันค่อนข้างหายาก
Ari Roth

10

ฉันเคยใช้มันมากในอดีตเพื่อทำงานกับอินพุตและเอาต์พุตสตรีม คุณสามารถทำรังอย่างดีและใช้ปัญหาที่อาจเกิดขึ้นจำนวนมาก (โดยการโทรออกโดยอัตโนมัติ) ตัวอย่างเช่น:

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

8

เพียงแค่เพิ่มสิ่งเล็กน้อยที่ฉันประหลาดใจไม่ได้เกิดขึ้น คุณลักษณะที่น่าสนใจที่สุดในการใช้งาน (ในความคิดของฉัน) คือไม่มีวิธีที่คุณออกจากบล็อกการใช้มันจะกำจัดวัตถุเสมอ รวมถึงผลตอบแทนและข้อยกเว้น

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

ไม่สำคัญว่าจะมีข้อผิดพลาดเกิดขึ้นหรือส่งคืนรายการหรือไม่ วัตถุ DbContext จะถูกกำจัดเสมอ


6

การใช้งานที่ยอดเยี่ยมอีกอย่างหนึ่งคือการโต้ตอบกับไดอะล็อก modal

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using

1
คุณหมายถึง frm.ShowDialog หรือเปล่า
UuDdLrLrSs

5

สรุปได้ว่าเมื่อคุณใช้ตัวแปรท้องถิ่นชนิดที่นำไปปฏิบัติIDisposable, เสมอโดยไม่มีข้อยกเว้นใช้1using

ถ้าคุณใช้ nonlocal IDisposableตัวแปรแล้วมักจะใช้รูปแบบIDisposable

สองกฎง่ายไม่มีข้อยกเว้น1 การป้องกันการรั่วไหลของทรัพยากรมิฉะนั้นจะเป็นความเจ็บปวดอย่างแท้จริงใน * ss


1) : ข้อยกเว้นเพียงอย่างเดียวคือ - เมื่อคุณจัดการข้อยกเว้น มันอาจจะเป็นรหัสน้อยกว่าที่จะเรียกDisposeอย่างชัดเจนในfinallyบล็อก


5

คุณสามารถใช้นามแฝงเนมสเปซได้โดยใช้ตัวอย่างต่อไปนี้:

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

นี่เรียกว่านามแฝงที่ใช้โดยที่คุณเห็นมันสามารถใช้เพื่อซ่อนการอ้างอิงที่ยืดยาวหากคุณต้องการให้ชัดเจนในโค้ดของคุณสิ่งที่คุณอ้างถึงเช่น

LegacyEntities.Account

แทน

CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account

หรือเพียงแค่

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

4

ที่น่าสนใจคุณสามารถใช้รูปแบบการใช้ / IDisposable สำหรับสิ่งที่น่าสนใจอื่น ๆ (เช่นจุดอื่น ๆ ที่ Rhino Mocks ใช้) โดยทั่วไปคุณสามารถใช้ประโยชน์จากความจริงที่ว่าคอมไพเลอร์จะเสมอเรียก .Dispose ที่ "ใช้" วัตถุ หากคุณมีบางสิ่งที่จำเป็นต้องเกิดขึ้นหลังจากการดำเนินการบางอย่าง ... สิ่งที่มีจุดเริ่มต้นและจุดสิ้นสุดที่แน่นอน ... จากนั้นคุณสามารถสร้างคลาส IDisposable ที่เริ่มการทำงานใน Constructor แล้วเสร็จในวิธีการกำจัด

สิ่งนี้ช่วยให้คุณใช้ไวยากรณ์ที่ดีมาก ๆ เพื่อแสดงการเริ่มต้นและสิ้นสุดของการดำเนินการที่ชัดเจน นี่ก็เป็นสิ่งที่ System.Transactions ทำงาน


3

เมื่อใช้ ADO.NET คุณสามารถใช้ keywork สำหรับสิ่งต่าง ๆ เช่นวัตถุการเชื่อมต่อของคุณหรือวัตถุผู้อ่าน ด้วยวิธีนี้เมื่อการบล็อกโค้ดเสร็จสมบูรณ์บล็อกนั้นจะถูกยกเลิกการเชื่อมต่อของคุณโดยอัตโนมัติ


2
ฉันจะเพิ่มที่บล็อกรหัสไม่ต้องทำ บล็อกการใช้จะกำจัดทรัพยากรแม้ในกรณีที่มีข้อยกเว้นที่ไม่สามารถจัดการได้
harpo

เพื่อให้ชัดเจนยิ่งขึ้นมันเป็นวิธีที่ทำให้มั่นใจได้ว่า Garbage Collector จะดูแลการจัดสรรของคุณเมื่อคุณต้องการแทนที่จะทำเมื่อมันต้องการ
moswald


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

2

การใช้ถูกใช้เมื่อคุณมีทรัพยากรที่คุณต้องการกำจัดหลังจากที่มีการใช้งาน

ตัวอย่างเช่นหากคุณจัดสรรทรัพยากรไฟล์และจำเป็นต้องใช้มันในรหัสส่วนเดียวสำหรับการอ่านหรือเขียนเพียงเล็กน้อยการใช้จะมีประโยชน์สำหรับการกำจัดทรัพยากรไฟล์ทันทีที่คุณทำเสร็จ

ทรัพยากรที่ใช้จำเป็นต้องใช้ IDisposable เพื่อให้ทำงานได้อย่างถูกต้อง

ตัวอย่าง:

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

1

คีย์เวิร์ดการใช้กำหนดขอบเขตสำหรับวัตถุจากนั้นจะกำจัดวัตถุเมื่อขอบเขตเสร็จสมบูรณ์ ตัวอย่างเช่น.

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

ดูที่นี่สำหรับบทความ MSDN ใน C # โดยใช้คำสำคัญ


1

ไม่ใช่ว่ามันมีความสำคัญเป็นพิเศษ แต่การใช้ยังสามารถใช้เพื่อเปลี่ยนทรัพยากรได้ทันที ใช่เป็นที่กล่าวถึงก่อนหน้านี้ แต่บางทีคุณอาจไม่ต้องการทรัพยากรที่ไม่ตรงกับแหล่งข้อมูลอื่น ๆ ในระหว่างการดำเนินการที่เหลือ ดังนั้นคุณต้องการกำจัดมันดังนั้นจึงไม่รบกวนที่อื่น


1

ขอบคุณที่แสดงความคิดเห็นด้านล่างฉันจะทำความสะอาดโพสต์นี้เล็กน้อย (ฉันไม่ควรใช้คำว่า 'การรวบรวมขยะ' ในเวลาขอโทษ):
เมื่อคุณใช้ใช้มันจะเรียกวิธีการ Dispose () บนวัตถุ ในตอนท้ายของขอบเขตการใช้งาน ดังนั้นคุณสามารถมีโค้ดการล้างข้อมูลที่ดีมากในวิธีการกำจัด () ของคุณ
สัญลักษณ์แสดงหัวข้อย่อยที่นี่ซึ่งหวังว่าจะได้รับสิ่งที่ไม่ถูกทำเครื่องหมายนี้: หากคุณใช้ IDisposable ให้แน่ใจว่าคุณเรียก GC.SuppressFinalize () ในการใช้งาน Dispose () ของคุณมิฉะนั้นการรวบรวมขยะอัตโนมัติจะพยายามเข้ามา จุดซึ่งอย่างน้อยก็จะเป็นการสิ้นเปลืองทรัพยากรหากคุณได้ทิ้ง () d ของมันไปแล้ว


มันมีผลทางอ้อม เนื่องจากคุณได้กำจัดวัตถุอย่างชัดเจนจึงไม่จำเป็นต้องมีการสรุปและดังนั้นจึงสามารถ GC ก่อนหน้านี้
Kent Boogaart

1

อีกตัวอย่างหนึ่งของการใช้งานที่มีเหตุผลซึ่งวัตถุจะถูกกำจัดทันที:

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

ทุกอย่างที่อยู่นอกวงเล็บปีกกาจะถูกกำจัดดังนั้นจึงเป็นการดีที่จะกำจัดวัตถุของคุณหากคุณไม่ได้ใช้มัน นี่เป็นเพราะถ้าคุณมีวัตถุ SqlDataAdapter และคุณใช้มันเพียงครั้งเดียวในวงจรชีวิตของแอปพลิเคชันและคุณเติมเพียงหนึ่งชุดข้อมูลและคุณไม่ต้องการมันอีกต่อไปคุณสามารถใช้รหัส:

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

1

คำสั่งการใช้มีกลไกอำนวยความสะดวกในการใช้วัตถุ IDisposable อย่างถูกต้อง ตามกฎแล้วเมื่อคุณใช้วัตถุ IDisposable คุณควรประกาศและสร้างอินสแตนซ์ในข้อความสั่งการใช้ คำสั่งการใช้เรียกวิธีการกำจัดบนวัตถุในวิธีที่ถูกต้องและ (เมื่อคุณใช้ตามที่แสดงก่อนหน้านี้) มันยังทำให้วัตถุตัวเองออกจากขอบเขตทันทีที่เรียกว่าการกำจัด ภายในบล็อกการใช้วัตถุนั้นเป็นแบบอ่านอย่างเดียวและไม่สามารถแก้ไขหรือกำหนดใหม่ได้

สิ่งนี้มาจาก: ที่นี่


1

สำหรับฉันชื่อ "using" นั้นค่อนข้างสับสนเล็กน้อยเนื่องจากเป็นคำสั่งที่จะนำเข้า Namespace หรือคำสั่ง (เช่นที่กล่าวถึงที่นี่) เพื่อจัดการข้อผิดพลาด

ชื่ออื่นสำหรับการจัดการข้อผิดพลาดจะดีมากและอาจเป็นชื่อที่ชัดเจนกว่านี้ก็ได้


1

นอกจากนี้ยังสามารถใช้สำหรับการสร้างขอบเขตสำหรับตัวอย่าง:

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

คำสั่งการใช้จะบอกให้. NET ปล่อยวัตถุที่ระบุในบล็อกการใช้เมื่อไม่จำเป็นต้องใช้อีกต่อไป ดังนั้นคุณควรใช้บล็อค 'using' สำหรับคลาสที่ต้องการล้างข้อมูลหลังจากนั้นเช่น System.IO Types


1

usingคำหลักมีอยู่สองวิธีใน C # ดังนี้

  1. เป็นคำสั่ง

    โดยทั่วไปเราใช้usingคำหลักเพื่อเพิ่มเนมสเปซในไฟล์ behind รหัสและคลาส จากนั้นมันจะทำให้มีคลาสอินเทอร์เฟซและคลาสนามธรรมทั้งหมดพร้อมทั้งเมธอดและคุณสมบัติในหน้าปัจจุบัน

    ตัวอย่าง:

    using System.IO;
  2. เป็นคำสั่ง

    นี่เป็นอีกวิธีหนึ่งในการใช้usingคำหลักใน C # มันมีบทบาทสำคัญในการปรับปรุงประสิทธิภาพในการรวบรวมขยะ

    usingคำสั่งเพื่อให้แน่ใจว่าทิ้ง () เรียกว่าแม้ว่าข้อยกเว้นเกิดขึ้นเมื่อคุณกำลังสร้างวัตถุและเรียกวิธีการคุณสมบัติและอื่น ๆ Dispose () เป็นวิธีการที่มีอยู่ในส่วนต่อประสาน IDisposable ที่ช่วยในการปรับใช้ Garbage Collection แบบกำหนดเอง กล่าวอีกนัยหนึ่งถ้าฉันกำลังดำเนินการฐานข้อมูล (Insert, Update, Delete) แต่อย่างใดข้อยกเว้นเกิดขึ้นแล้วที่นี่คำสั่งการใช้ปิดการเชื่อมต่อโดยอัตโนมัติ ไม่จำเป็นต้องเรียกวิธีการเชื่อมต่อปิด () อย่างชัดเจน

    อีกหนึ่งปัจจัยที่สำคัญคือช่วยในการรวมการเชื่อมต่อ การเชื่อมต่อรวมกันใน. NET ช่วยในการกำจัดการปิดการเชื่อมต่อฐานข้อมูลหลายครั้ง มันจะส่งวัตถุการเชื่อมต่อไปยังสระว่ายน้ำสำหรับการใช้งานในอนาคต (เรียกฐานข้อมูลต่อไป) ครั้งต่อไปที่การเชื่อมต่อฐานข้อมูลถูกเรียกจากแอปพลิเคชันของคุณพูลการเชื่อมต่อจะดึงข้อมูลวัตถุที่มีอยู่ในกลุ่ม ดังนั้นช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชัน ดังนั้นเมื่อเราใช้คำสั่ง use ผู้ควบคุมจะส่งวัตถุไปยังพูลการเชื่อมต่อโดยอัตโนมัติไม่จำเป็นต้องเรียกใช้เมธอด Close () และ Dispose () อย่างชัดเจน

    คุณสามารถทำสิ่งเดียวกันกับสิ่งที่ข้อความการใช้กำลังทำอยู่โดยใช้บล็อก try-catch และเรียกใช้ Dispose () ภายในบล็อกสุดท้าย แต่ข้อความที่ใช้จะทำการโทรออกโดยอัตโนมัติเพื่อทำให้โค้ดสะอาดและสวยงามยิ่งขึ้น ภายในบล็อกการใช้วัตถุนั้นเป็นแบบอ่านอย่างเดียวและไม่สามารถแก้ไขหรือกำหนดใหม่ได้

    ตัวอย่าง:

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

ในรหัสก่อนหน้านี้ฉันไม่ได้ปิดการเชื่อมต่อใด ๆ มันจะปิดโดยอัตโนมัติ usingคำสั่งจะเรียก conn.close () โดยอัตโนมัติเนื่องจากการusingคำสั่ง ( using (SqlConnection conn = new SqlConnection(connString)) และที่เหมือนกันสำหรับวัตถุ SqlDataReader และหากมีข้อยกเว้นเกิดขึ้นก็จะปิดการเชื่อมต่อโดยอัตโนมัติ

สำหรับข้อมูลเพิ่มเติมโปรดดูที่การใช้งานและความสำคัญของการใช้ใน C #



-1

ใช้เป็นคำสั่งเรียกการกำจัดบนวัตถุที่ระบุโดยอัตโนมัติ วัตถุต้องใช้อินเทอร์เฟซสำหรับ IDisposable มันเป็นไปได้ที่จะใช้วัตถุหลาย ๆ อันในคำสั่งเดียวตราบใดที่มันเป็นชนิดเดียวกัน

CLR แปลงรหัสของคุณเป็น MSIL และการใช้คำสั่งจะถูกแปลเป็นลองและสุดท้ายบล็อก นี่คือลักษณะที่ข้อความการใช้แสดงใน IL คำสั่งที่ใช้ถูกแปลเป็นสามส่วน: การได้มาการใช้งานและการกำจัด ทรัพยากรได้รับมาก่อนจากนั้นการใช้งานจะถูกล้อมรอบในข้อความสั่ง try พร้อมกับประโยคสุดท้าย จากนั้นวัตถุจะถูกกำจัดในประโยคสุดท้าย


-3

ใช้ส่วนคำสั่งที่ใช้ในการกำหนดขอบเขตสำหรับตัวแปรเฉพาะ ตัวอย่างเช่น:

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

สิ่งนี้อาจทำให้บางคนพลาดการใช้เพื่อกำจัดวัตถุ บางทีคุณอาจสับสนกับโค้ดบล็อกถ้าคุณต้องการ จำกัด ขอบเขตของตัวแปรคุณสามารถใช้โค้ดบล็อกแบบซ้อนสำหรับสิ่งนั้น: โมฆะสาธารณะแบบคงที่หลัก (สตริงสตริง [] args) {{// บล็อกโค้ดซ้อน}}
luiseduardohd
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.