เครื่องหมายตัวหนอนหน้าชื่อฟังก์ชันหมายถึงอะไรใน C #


164

ฉันกำลังดูรหัสและมีคำสั่งนี้:

~ConnectionManager()
{
    Dispose(false);
}

คลาสใช้IDisposableอินเทอร์เฟซ แต่ฉันไม่ทราบว่าเป็นส่วนหนึ่งของที่ตัวหนอน (~) ใช้

คำตอบ:


213

~ เป็นตัวทำลาย

  1. Destructors ถูกเรียกใช้โดยอัตโนมัติและไม่สามารถเรียกใช้ได้อย่างชัดเจน
  2. Destructors ไม่สามารถโหลดได้มากเกินไป ดังนั้นคลาสสามารถมีหนึ่ง destructor ได้มากที่สุด
  3. Destructors ไม่ได้รับการสืบทอด ดังนั้นคลาสไม่มี destructors อื่นนอกเหนือจากสิ่งซึ่งอาจถูกประกาศในนั้น
  4. Destructors ไม่สามารถใช้กับ structs ได้ พวกเขาจะใช้กับชั้นเรียนเท่านั้น อินสแตนซ์จะมีสิทธิ์ถูกทำลายได้เมื่อไม่สามารถใช้งานโค้ดได้อีกต่อไป
  5. การดำเนินการของ destructor สำหรับอินสแตนซ์อาจเกิดขึ้นได้ตลอดเวลาหลังจากที่อินสแตนซ์มีสิทธิ์สำหรับการทำลาย
  6. เมื่ออินสแตนซ์ถูกทำลาย destructors ในห่วงโซ่มรดกของมันจะถูกเรียกตามลำดับจากมากที่สุดมาถึงน้อยที่สุดที่ได้รับ

สรุป

ใน C # นั้นวิธีการ Finalize จะทำการดำเนินการที่ destructor C ++ มาตรฐานจะทำ ใน C # คุณไม่ได้ตั้งชื่อ Finalize - คุณใช้ไวยากรณ์ C + destructor ของการวางสัญลักษณ์ tilde (~) หน้าชื่อของคลาส

ทิ้ง

เป็นที่นิยมในการกำจัดของวัตถุในClose()หรือDispose()วิธีการที่สามารถเรียกได้ว่าชัดเจนโดยผู้ใช้ของชั้น จบการทำงาน (destructor) ถูกเรียกโดย GC

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

จะใช้อะไรดี?

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


3
ฉันไม่รู้ว่ามันเคยเป็นอย่างไรในอดีต แต่ตอนนี้ผู้ทำลายล้างได้รับมรดก ตรวจสอบลิงค์นี้สำหรับข้อมูลเพิ่มเติม (ตรวจสอบตัวอย่างในตอนท้าย): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex

1
@RononDex จุดที่ 3 ของหน้าเว็บที่คุณเชื่อมโยงไปยังสถานะ"Finalizers ไม่สามารถสืบทอดได้"ซึ่งขัดแย้งกับความคิดเห็นของคุณ มันเป็นเรื่องที่ยอมรับกันค่อนข้างสับสนเพราะในขณะที่พวกเขาไม่สามารถสืบทอดได้" Finalizeวิธีการนี้ถูกเรียกซ้ำสำหรับทุกกรณีในห่วงโซ่การสืบทอดซ้ำๆ โปรดทราบว่านั่นไม่ใช่พฤติกรรมเดียวกันที่คุณจะได้รับจากตัวทำลายที่สืบทอดได้
Mark Amery

@ MarkAmery อาฉันเห็นดังนั้นโดยทั่วไปแล้วพวกเขาได้รับเรียกในลำดับที่กลับรายการเมื่อเทียบกับสิ่งที่สืบทอดมา?
RononDex

45

นี่คือfinalizer พูดตามตรงคุณไม่ควรเขียน finalizer บ่อยนัก คุณจะต้องเขียนเพียงอย่างเดียวถ้า:

  • คุณสามารถเข้าถึงทรัพยากรที่ไม่มีการจัดการโดยตรง (เช่นผ่านทางIntPtr) และคุณไม่สามารถใช้งานได้SafeHandleซึ่งทำให้ง่ายขึ้น
  • คุณกำลังนำไปใช้IDisposableในชั้นเรียนที่ไม่ได้ปิดผนึก (ความชอบของฉันคือการปิดคลาสนอกจากว่าพวกมันถูกออกแบบมาเพื่อสืบทอด) finalizer เป็นส่วนหนึ่งของรูปแบบการกำหนดมาตรฐานในกรณีดังกล่าว

9

มันถูกใช้เพื่อระบุ destructor สำหรับชั้นเรียน


12
ทั้งคู่ถูกต้องขึ้นอยู่กับข้อกำหนด C # ที่คุณอ่าน MS ล่าสุด (unified C # 3.0) หมายถึงพวกเขาเป็น destructors (เช่นส่วนที่ 10.13) แต่ข้อมูลจำเพาะ ECMA อ้างถึงพวกเขาเป็น finalizers
Jon Skeet

@ 1800INFORMATION: องค์ประกอบวากยสัมพันธ์เรียกว่า destructor อย่างถูกต้อง หากคลาสมี destructor คอมไพเลอร์ C # จะสร้าง finalizer อัตโนมัติซึ่งรวมถึงtry/finallyบล็อกที่ไม่มีประโยชน์โดยทั่วไปที่ช่วยให้มั่นใจได้ว่าFinalizeวิธีการหลักได้รับการเรียก สิ่งส่วนใหญ่ที่เป็นจริงของ destructors เป็นจริงของ finalizers และในทางกลับกัน แต่คำพูดหมายถึงสิ่งที่แตกต่างกันเล็กน้อย
supercat

4

เช่นเดียวกับ C ++ มันเป็นตัวทำลายล้าง อย่างไรก็ตามใน C # คุณไม่ได้เรียกมันอย่างชัดเจนมันถูกเรียกใช้เมื่อรวบรวมวัตถุ


3

ดูDestructors (C # Programming Guide) อย่างไรก็ตามโปรดทราบว่าโปรแกรมเมอร์ไม่สามารถควบคุมได้เมื่อมีการเรียกตัว destructor ซึ่งแตกต่างจาก C ++ เนื่องจากจะถูกกำหนดโดยตัวรวบรวมขยะ


1

~ มักจะหมายถึง deconstructor ซึ่งจะวิ่งไปทางขวาก่อนที่วัตถุจะตาย

นี่คือคำอธิบายของ C # deconstructors ที่ฉันพบ


4
คำที่ถูกต้องควรเป็น destructor / finalizer ไม่ใช่ตัวแยกส่วน Deconstructor หมายถึงไวยากรณ์ในการ deconstructor คอนสตรัคเตอร์
Eriawan Kusumawardhono
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.