การตั้งค่าวัตถุเป็น Null / ไม่มีอะไรหลังจากใช้ใน. NET


187

คุณควรตั้งค่าวัตถุทั้งหมดเป็นnull( Nothingใน VB.NET) เมื่อคุณทำเสร็จแล้ว?

ฉันเข้าใจว่าใน. NET มันเป็นสิ่งสำคัญในการกำจัดอินสแตนซ์ของวัตถุใด ๆ ที่ใช้IDisposableอินเทอร์เฟซเพื่อปล่อยทรัพยากรบางอย่างแม้ว่าวัตถุยังสามารถเป็นบางสิ่งหลังจากที่มันถูกกำจัด (ดังนั้นisDisposedคุณสมบัติในรูปแบบ) ดังนั้นฉันคิดว่ามัน ในหน่วยความจำหรืออย่างน้อยก็ในบางส่วน

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

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

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


4
+1 คำถามที่ยอดเยี่ยม มีใครรู้บ้างไหมว่ามีเหตุการณ์ใดที่คอมไพเลอร์จะปรับการบ้านให้เหมาะสมกันโดยสิ้นเชิง? นั่นคือมีใครดูที่ MSIL ภายใต้สถานการณ์ที่แตกต่างกันและตั้งข้อสังเกต IL สำหรับการตั้งค่าวัตถุให้เป็นโมฆะ (หรือขาดมัน)
Tim Medora

คำตอบ:


73

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

ฉันคิดว่านี่เป็นการรักษาที่ดี:

ขุดลงใน IDisposable

และนี่

ทำความเข้าใจกับ IDisposable

ไม่มีจุดใดในการพยายามเดา GC และกลยุทธ์การจัดการในจุดที่สองเพราะมันเป็นการปรับและทึบแสง มีการสนทนาที่ดีเกี่ยวกับผลงานภายในกับ Jeffrey Richter บน Dot Net Rocks ที่นี่: Jeffrey Richter ในรุ่นหน่วยความจำของ Windowsและหนังสือ Richters CLR ผ่าน C # ตอนที่ 20 มีการรักษาที่ยอดเยี่ยม:


6
กฎเกี่ยวกับการไม่ตั้งค่าเป็นโมฆะไม่ใช่ "แข็งและเร็ว" ... หากวัตถุถูกวางบนกองวัตถุขนาดใหญ่ (ขนาดคือ> 85K) มันจะช่วย GC ถ้าคุณตั้งค่าวัตถุเป็น null เมื่อคุณทำเสร็จแล้ว ใช้มัน
Scott Dorman

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

21
ธุรกิจทั้งหมดของ "ไม่เพิ่มประสิทธิภาพก่อนกำหนด" ฟังดูเหมือน "ชอบช้าและไม่ต้องกังวลเพราะซีพียูเริ่มเร็วขึ้นและแอพ CRUD ไม่ต้องการความเร็วเลย" มันอาจเป็นฉัน :)
BobbyShaftoe

19
ความหมายจริงๆคือ "The Garbage Collector ดีกว่าในการจัดการหน่วยความจำมากกว่าที่คุณเป็น" นั่นอาจเป็นเพียงฉัน :)
BobRodes

2
@ BobShaftoe: มันอาจจะผิดที่จะพูดว่า "การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นสิ่งที่ไม่ดีเสมอ" เพราะมันจะข้ามไปยังจุดที่ตรงกันข้ามมากที่สุดของ "เสียงมากขึ้นเช่น 'ชอบช้า' ไม่มีโปรแกรมเมอร์ที่เหมาะสมจะพูดอย่างใดอย่างหนึ่ง มันเกี่ยวกับความแตกต่างกันนิดหน่อยและฉลาดในการเพิ่มประสิทธิภาพของคุณ ฉันต้องกังวลเกี่ยวกับความชัดเจนของรหัสและการทดสอบจริงจากนั้นฉันเห็นผู้คนจำนวนมาก (รวมถึงตัวฉันเองเมื่อฉันยังเด็ก) ใช้เวลามากเกินไปในการสร้างอัลกอริทึม "สมบูรณ์แบบ" เพียงเพื่อประหยัด 0.1ms 100,000 การทำซ้ำทั้งหมดในขณะที่การอ่านถูกยิงอย่างสมบูรณ์
Brent Rittenhouse

36

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

เช่น

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

จะอนุญาตให้วัตถุที่อ้างอิงโดย someType เป็น GC'd หลังจากการเรียกไปที่ "DoSomething" แต่

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is NOT eligible for garbage collection yet
    // because that variable is used at the end of the method         

    // ... rest of method not using 'someType' ...
    someType = null;
}

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


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

1
วิธีที่ต้องการเพื่อให้แน่ใจว่าพวกเขายังมีชีวิตอยู่คือการใช้GC.KeepAlive(someType); ดูที่ericlippert.com/2013/06/10/construction-destruction
NotMe

14

ไม่มีวัตถุที่ไม่เป็นโมฆะ คุณสามารถตรวจสอบhttp://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspxสำหรับข้อมูลเพิ่มเติม แต่ตั้งค่าสิ่งต่าง ๆ เป็นโมฆะจะไม่ทำอะไรเลยยกเว้นรหัสของคุณสกปรก


1
ดีและคำอธิบายรายละเอียดเกี่ยวกับหน่วยความจำในลิงค์ที่แชร์
user2323308

ลิงก์เสีย ไม่มีเนื้อหาที่เชื่อมโยงคำตอบนี้ค่อนข้าง useles และควรถูกลบ
Imre Pühvel


7

โดยทั่วไปแล้วไม่จำเป็นต้องมีวัตถุว่างหลังจากใช้งาน แต่ในบางกรณีฉันพบว่ามันเป็นแนวปฏิบัติที่ดี

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

this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();

เป็นการดีที่จะลบฟิลด์หลังจากทิ้งแล้วรับ NullPtrEx ที่บรรทัดที่ใช้ฟิลด์อีกครั้ง มิฉะนั้นคุณอาจพบข้อผิดพลาดบางอย่างที่ซ่อนเร้นในบรรทัด (ขึ้นอยู่กับสิ่งที่ DoSomething ทำ)


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

3
Ctrl + F .Dispose()สำหรับ หากคุณพบว่าคุณใช้ IDisposable ไม่ถูกต้อง การใช้งานเฉพาะสำหรับวัตถุที่ใช้แล้วทิ้งควรอยู่ในขอบเขตของการใช้บล็อก และหลังจากการใช้บล็อกคุณจะไม่สามารถเข้าถึงได้myFieldอีกต่อไป และภายในบล็อกการใช้การตั้งค่าnullไม่จำเป็นต้องใช้บล็อกการใช้งานจะกำจัดวัตถุให้คุณ
Suamere

7

โอกาสที่รหัสของคุณจะไม่มีโครงสร้างที่แน่นพอถ้าคุณรู้สึกว่าจำเป็นต้องมีnullตัวแปร

มีหลายวิธีในการ จำกัด ขอบเขตของตัวแปร:

ตามที่กล่าวถึงโดยSteve Tranby

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

ในทำนองเดียวกันคุณสามารถใช้วงเล็บปีกกา:

{
    // Declare the variable and use it
    SomeObject object = new SomeObject()
}
// The variable is no longer available

ฉันพบว่าการใช้วงเล็บปีกกาที่ไม่มี "หัวเรื่อง" เพื่อล้างรหัสและช่วยให้เข้าใจได้ง่ายขึ้น


ฉันพยายามใช้ขอบเขตท้องถิ่นที่กำหนดเองหนึ่งครั้ง (ส่วนใหญ่เป็น Smarta $$) บริษัท ระเบิด
Suamere

ในหมายเหตุอื่น: นี่เป็นเพราะคอมไพเลอร์ c # จะค้นหาตัวแปรที่มีการกำหนดขอบเขตแบบท้องถิ่นที่ใช้ IDisposable และจะเรียกใช้. ทิ้ง (เวลาส่วนใหญ่) เมื่อขอบเขตสิ้นสุดลง อย่างไรก็ตาม ... การเชื่อมต่อ SQL เป็นครั้งใหญ่เมื่อ. Disis () ไม่เคยถูกปรับให้เหมาะสม มีบางประเภทที่ต้องให้ความสนใจอย่างชัดเจนดังนั้นฉันมักจะทำสิ่งต่าง ๆ อย่างชัดเจนดังนั้นฉันจึงไม่ถูกกัด
Suamere

5

ครั้งเดียวที่คุณควรตั้งค่าตัวแปรเป็นโมฆะคือเมื่อตัวแปรไม่ออกจากขอบเขตและคุณไม่ต้องการข้อมูลที่เกี่ยวข้องอีกต่อไป มิฉะนั้นก็ไม่จำเป็น


2
เป็นเรื่องจริง แต่ก็หมายความว่าคุณควรจะปรับรหัสของคุณใหม่ ฉันไม่คิดว่าฉันจะต้องประกาศตัวแปรนอกขอบเขตที่ตั้งใจไว้
Karl Seguin

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

5

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

จากนั้นคุณอาจทำเพราะคุณไม่ต้องการโทรทิ้งสองครั้งเนื่องจากการกำจัดบางอย่างอาจไม่สามารถใช้งานได้อย่างถูกต้องและโยน System.ObjectDisposed ข้อยกเว้น

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }

ดีที่สุดที่จะติดตามสิ่งนี้ด้วยการตั้งค่าสถานะแยกต่างหากอาจจะ
Thulani Chivandikwa

3

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

ใช่คุณควรโทร.Dispose()หรือ.Close()ทำอะไรก็ตามเมื่อคุณทำเสร็จแล้ว ไม่ว่าจะเป็นไฟล์ที่จับการเชื่อมต่อฐานข้อมูลหรือวัตถุที่ใช้แล้วทิ้ง

แยกออกมาจากรูปแบบการใช้งานจริงของ LazyLoad

บอกว่าผมมีและอินสแตนซ์ของ ObjA มีทรัพย์สินของประชาชนที่เรียกว่าของclass AClass APropBclass B

ภายในPropBใช้ตัวแปรส่วนตัวของ_Bและค่าเริ่มต้นเป็นโมฆะ เมื่อPropB.Get()ถูกนำมาใช้มันจะตรวจสอบเพื่อดูว่า_PropBเป็นโมฆะและถ้ามันเป็นเปิดทรัพยากรที่จำเป็นในการยกตัวอย่างออกเป็นB ก็จะส่งกลับแล้ว_PropB_PropB

สำหรับประสบการณ์ของฉันนี่เป็นเคล็ดลับที่มีประโยชน์จริงๆ

ในกรณีที่จำเป็นต้องมีค่าว่างหากคุณรีเซ็ตหรือเปลี่ยนแปลง A ในทางที่เนื้อหาของ_PropBเป็นค่าย่อยของค่าก่อนหน้านี้Aคุณจะต้องทิ้งและค่าว่าง_PropBเพื่อให้ LazyLoad สามารถรีเซ็ตเพื่อดึงค่าที่ถูกต้องหากรหัส ต้องการมัน

หากคุณทำ_PropB.Dispose()และหลังจากนั้นไม่นานคาดว่าการตรวจสอบค่า null สำหรับ LazyLoad จะประสบความสำเร็จจะไม่เป็นโมฆะและคุณจะดูข้อมูลเก่า ผลคุณต้องเป็นโมฆะหลังจากนั้นDispose()เพื่อให้แน่ใจ

ฉันหวังว่ามันจะเป็นอย่างอื่น แต่ตอนนี้ฉันได้รับรหัสแสดงพฤติกรรมนี้หลังจากที่ฟังก์ชั่นDispose()a _PropBและนอกฟังก์ชั่นการโทรที่ใช้ Dispose (และเกือบจะอยู่นอกขอบเขต) เสาส่วนตัวยังคงไม่ว่าง และข้อมูลเก่ายังคงอยู่ที่นั่น

ในที่สุดทรัพย์สินที่จำหน่ายจะเป็นโมฆะ แต่นั่นไม่ใช่การกำหนดจากมุมมองของฉัน

เหตุผลหลักเป็น alludes dbkk คือภาชนะแม่ ( ObjAกับPropB) คือการรักษาตัวอย่างของในขอบเขตแม้จะมี_PropBDispose()


ตัวอย่างที่ดีแสดงให้เห็นว่าการตั้งค่าเป็นโมฆะด้วยตนเองหมายถึงข้อผิดพลาดร้ายแรงสำหรับผู้โทรซึ่งเป็นสิ่งที่ดี
โรล

1

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

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

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


1

ลองดูที่บทความนี้เช่นกัน: http://www.codeproject.com/KB/cs/idisposable.aspx

ส่วนใหญ่แล้วการตั้งค่าวัตถุให้เป็นโมฆะจะไม่มีผลกระทบใด ๆ ครั้งเดียวที่คุณควรทำเช่นนั้นคือหากคุณทำงานกับ "วัตถุขนาดใหญ่" ซึ่งมีขนาดใหญ่กว่า 84K หนึ่งขนาด (เช่นบิตแมป)


1

สตีเฟ่นเคลียร์อธิบายได้ดีมากในโพสต์นี้: ฉันควรตั้งค่าตัวแปรเป็นศูนย์เพื่อการรวบรวมขยะมูลฝอยหรือไม่

พูดว่า:

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

ซึ่งหมายความว่าในวิธีการปกติ (ไม่นับและไม่ตรงกัน) คุณไม่ได้ตั้งค่าตัวแปรโลคอลพารามิเตอร์เมธอดหรือฟิลด์อินสแตนซ์เป็นโมฆะ

(แม้ว่าคุณจะใช้งาน IDisposable.Dispose คุณก็ยังไม่ควรตั้งค่าตัวแปรเป็นโมฆะ)

สิ่งที่สำคัญที่เราควรจะต้องพิจารณาเป็นทุ่งแบบคงที่

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

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

สรุป:

ฟิลด์คงที่ ; เกี่ยวกับมัน. สิ่งอื่นใดคือการเสียเวลา


0

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

โดยส่วนตัวแล้วฉันมักจะตั้งค่าตัวแปรเป็นโมฆะเมื่อฉันทำกับพวกเขาเป็นรูปแบบของเอกสารด้วยตนเอง ฉันไม่ได้ประกาศใช้แล้วตั้งค่าเป็นโมฆะในภายหลัง - ฉันเป็นโมฆะทันทีหลังจากไม่ต้องการใช้อีกต่อไป ฉันกำลังพูดอย่างชัดเจน "ฉันทำอย่างเป็นทางการกับคุณ ... ไปแล้ว ... "

การลบล้างจำเป็นในภาษา GC'd ไหม ไม่มันมีประโยชน์สำหรับ GC หรือไม่? อาจจะใช่บางทีไม่ทราบแน่นอนเพราะการออกแบบฉันไม่สามารถควบคุมมันได้จริงและไม่ว่าคำตอบของวันนี้กับรุ่นนี้หรือการใช้งาน GC ในอนาคตอาจเปลี่ยนคำตอบที่อยู่นอกเหนือการควบคุมของฉัน บวกถ้า / เมื่อ nulling ถูกปรับออกมันน้อยกว่าความคิดเห็นแฟนซีถ้าคุณจะ

ฉันคิดว่ามันทำให้ความตั้งใจของฉันชัดเจนกว่าคนโง่ที่น่าสงสารคนต่อไปที่ตามรอยเท้าของฉันและถ้ามัน"อาจ"อาจช่วย GC ในบางครั้งมันก็คุ้มกับฉัน ส่วนใหญ่ทำให้ฉันรู้สึกเป็นระเบียบและชัดเจนและ Mongo ชอบที่จะรู้สึกเป็นระเบียบและชัดเจน :)

ฉันดูที่มันเช่นนี้: ภาษาการเขียนโปรแกรมมีอยู่เพื่อให้ผู้คนให้ความคิดเกี่ยวกับเจตนาและคอมไพเลอร์คำของานว่าจะทำอย่างไร - คอมไพเลอร์แปลงการร้องขอที่เป็นภาษาอื่น (บางครั้ง) สำหรับ CPU - ซีพียูสามารถบีบแตรภาษาที่คุณใช้การตั้งค่าแท็บความคิดเห็นการเน้นโวหารชื่อตัวแปร ฯลฯ - ซีพียูทั้งหมดเกี่ยวกับบิตสตรีมที่บอกว่าการลงทะเบียนและ opcodes และตำแหน่งหน่วยความจำของซอ หลายสิ่งที่เขียนด้วยโค้ดไม่ได้แปลงเป็นซีพียูที่ใช้ตามลำดับที่เราระบุ C, C ++, C #, Lisp, Babel, Assembler หรืออะไรก็ตามที่เป็นทฤษฏีมากกว่าความเป็นจริงที่เขียนเป็นแถลงการณ์การทำงาน สิ่งที่คุณเห็นไม่ใช่สิ่งที่คุณได้รับแม้กระทั่งในภาษาแอสเซมเบลอร์

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

มีข้อยกเว้นกฎใด ๆ ในสถานการณ์ที่มีหน่วยความจำแบบระเหยหน่วยความจำแบบคงที่สภาพการแข่งขันซิงเกิลการใช้ข้อมูล "เก่า" และการเน่าทุกประเภทนั้นแตกต่าง: คุณต้องจัดการหน่วยความจำของคุณเองการล็อคและการลบล้างเป็นเรื่องเนื่องจากหน่วยความจำ GC'd Universe - หวังว่าทุกคนจะเข้าใจเรื่องนั้น เวลาที่เหลือด้วยภาษา GC'd มันเป็นเรื่องของสไตล์มากกว่าความจำเป็นหรือการเพิ่มประสิทธิภาพที่รับประกัน

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


0

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

ฉันเชื่อว่ากรอบการกำจัดจะช่วยให้โยน ObjectDisposedException ซึ่งมีความหมายมากขึ้น การไม่ตั้งค่ากลับเป็นค่า null จะดีกว่าด้วยเหตุผลนั้น


-1

วัตถุบางอย่างคิดว่า.dispose()วิธีการที่บังคับให้ทรัพยากรถูกลบออกจากหน่วยความจำ


11
ไม่มันไม่; Dispose () ไม่ได้รวบรวมวัตถุ - มันถูกใช้เพื่อดำเนินการล้างค่าที่กำหนดไว้โดยทั่วไปแล้วจะปล่อยทรัพยากรที่ไม่มีการจัดการ
Marc Gravell

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