เหตุใด C # จึงใช้วิธีการไม่ใช่เสมือนโดยค่าเริ่มต้น


105

ต่างจาก Java เหตุใด C # จึงถือว่าเมธอดไม่ใช่ฟังก์ชันเสมือนตามค่าเริ่มต้น มีแนวโน้มที่จะเป็นปัญหาด้านประสิทธิภาพมากกว่าผลลัพธ์ที่เป็นไปได้อื่น ๆ หรือไม่?

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


1
คำตอบที่พูดถึงเหตุผลประสิทธิภาพมองข้ามความจริงที่ว่า C # คอมไพเลอร์ส่วนใหญ่รวบรวมวิธีการโทรไปยังcallvirtและไม่ได้โทร ด้วยเหตุนี้ใน C # จึงเป็นไปไม่ได้ที่จะมีเมธอดที่ทำงานแตกต่างกันหากการthisอ้างอิงเป็นโมฆะ ดูที่นี่สำหรับข้อมูลเพิ่มเติม
Andy

จริง! คำสั่งเรียก IL ส่วนใหญ่สำหรับการโทรไปยังวิธีการแบบคงที่
RBT

1
ความคิดของสถาปนิก C # 's Anders Hejlsberg ของที่นี่และที่นี่
RBT

คำตอบ:


98

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

virtualวิธีการยังสามารถมีผลกระทบเล็กน้อย อย่างไรก็ตามนี่ไม่น่าจะเป็นเหตุผลหลัก


7
โดยส่วนตัวแล้วฉันสงสัยในส่วนนั้นเกี่ยวกับประสิทธิภาพ แม้กระทั่งสำหรับฟังก์ชันเสมือนจริงคอมไพเลอร์ยังสามารถระบุตำแหน่งที่จะแทนที่ได้callvirtโดยใช้callรหัส IL อย่างง่าย(หรือแม้แต่ดาวน์สตรีมเพิ่มเติมเมื่อ JITting) Java HotSpot ก็เช่นเดียวกัน คำตอบที่เหลือคือเฉพาะจุด
Konrad Rudolph

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

71
ชั้นเรียนปิดผนึกทำให้ฉันอยากจะต่อยเด็กทารก
mxmissile

6
@mxmissile: ฉันก็เช่นกัน แต่การออกแบบ API ที่ดีนั้นยากอยู่ดี ฉันคิดว่าการปิดผนึกตามค่าเริ่มต้นนั้นเหมาะสมอย่างยิ่งสำหรับโค้ดที่คุณเป็นเจ้าของ บ่อยกว่านั้นโปรแกรมเมอร์คนอื่น ๆ ในทีมของคุณไม่ได้พิจารณาการสืบทอดเมื่อพวกเขาใช้คลาสนั้นที่คุณต้องการและการปิดผนึกโดยค่าเริ่มต้นจะถ่ายทอดข้อความนั้นได้ค่อนข้างดี
Roman Starkov

49
หลายคนเป็นโรคจิตด้วยไม่ได้หมายความว่าเราควรฟังพวกเขา เสมือนควรเป็นค่าเริ่มต้นใน C # โค้ดควรขยายได้โดยไม่ต้องเปลี่ยนการใช้งานหรือเขียนใหม่ทั้งหมด ผู้ที่ปกป้อง API ของตนมากเกินไปมักจะจบลงด้วย API ที่ใช้งานไม่ได้หรือใช้ไปแล้วครึ่งหนึ่งซึ่งเลวร้ายยิ่งกว่าสถานการณ์ที่มีคนใช้มันในทางที่ผิด
Chris Nicola

89

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

เหตุผลส่วนใหญ่อ่านให้ฉันฟังเหมือนข้อโต้แย้ง "ถ้าเราให้พลังคุณอาจทำร้ายตัวเอง" จากโปรแกรมเมอร์?!

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

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

การไม่เสมือนโดยค่าเริ่มต้นทำให้ชีวิตของฉันยากขึ้น

UPDATE:มีการชี้ให้เห็น [ค่อนข้างถูกต้อง] ว่าฉันไม่ได้ตอบคำถามจริงๆ ดังนั้น - และขออภัยที่ค่อนข้างช้า ....

ฉันอยากจะเขียนอะไรบางอย่างที่มีเหตุผลเช่น "C # ใช้วิธีการแบบไม่เสมือนโดยค่าเริ่มต้นเนื่องจากมีการตัดสินใจที่ไม่ถูกต้องซึ่งให้ความสำคัญกับโปรแกรมมากกว่าโปรแกรมเมอร์" (ฉันคิดว่าอาจมีเหตุผลบ้างตามคำตอบอื่น ๆ ของคำถามนี้เช่นประสิทธิภาพ (การเพิ่มประสิทธิภาพก่อนกำหนดใคร?) หรือการรับประกันพฤติกรรมของชั้นเรียน)

อย่างไรก็ตามฉันตระหนักดีว่าฉันแค่แสดงความคิดเห็นของฉันไม่ใช่คำตอบที่ชัดเจนที่ Stack Overflow ต้องการ แน่นอนฉันคิดว่าในระดับสูงสุดคำตอบที่ชัดเจน (แต่ไม่เป็นประโยชน์) คือ:

โดยค่าเริ่มต้นจะไม่เสมือนจริงเนื่องจากนักออกแบบภาษามีการตัดสินใจและนั่นคือสิ่งที่พวกเขาเลือก

ตอนนี้ฉันเดาเหตุผลที่แน่นอนที่พวกเขาตัดสินใจว่าเราจะไม่ .... โอ้รอ! บันทึกการสนทนา!

ดังนั้นดูเหมือนว่าคำตอบและความคิดเห็นที่นี่เกี่ยวกับอันตรายของการลบล้าง API และความจำเป็นในการออกแบบอย่างชัดเจนสำหรับการสืบทอดอยู่ในแนวทางที่ถูกต้อง แต่ทั้งหมดขาดแง่มุมที่สำคัญไปชั่วขณะ: ข้อกังวลหลักของ Anders คือการรักษาโดยนัยของคลาสหรือ API สัญญาข้ามรุ่น และฉันคิดว่าเขากังวลมากขึ้นเกี่ยวกับการอนุญาตให้แพลตฟอร์ม. Net / C # เปลี่ยนแปลงภายใต้รหัสแทนที่จะกังวลเกี่ยวกับการเปลี่ยนรหัสผู้ใช้ที่ด้านบนของแพลตฟอร์ม (และมุมมอง "เชิงปฏิบัติ" ของเขาตรงข้ามกับของฉันเพราะเขามองจากอีกด้านหนึ่ง)

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


2
ไม่เห็นด้วยมากกว่านี้ น่าผิดหวังมากเมื่อใช้ API ของบุคคลที่สามและต้องการลบล้างพฤติกรรมบางอย่างและไม่สามารถทำได้
Andy

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

2
ตอนนี้ถ้ามีเพียงคุณลักษณะตัวแก้ไขใน Visual Studio เพื่อแท็กวิธีการ / คุณสมบัติทั้งหมดโดยอัตโนมัติเป็นvirtual... Visual Studio add-in ใคร?
kevinarpe

1
ในขณะที่ฉันเห็นด้วยกับคุณด้วยใจจริงนี่ไม่ใช่คำตอบอย่างแน่นอน
Chris Morgan

2
เมื่อพิจารณาถึงแนวทางการพัฒนาที่ทันสมัยเช่นการพึ่งพาการพึ่งพากรอบการเยาะเย้ยและ ORM ดูเหมือนชัดเจนว่านักออกแบบ C # ของเราพลาดจุดสำคัญไปเล็กน้อย เป็นเรื่องน่าผิดหวังมากที่ต้องทดสอบการพึ่งพาเมื่อคุณไม่สามารถแทนที่คุณสมบัติตามค่าเริ่มต้นได้
Jeremy Holovacs

17

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


12

เพื่อสรุปสิ่งที่คนอื่นพูดมีสาเหตุสองสามประการ:

1-ใน C # มีหลายสิ่งในไวยากรณ์และความหมายที่มาจาก C ++ โดยตรง ความจริงที่ว่าวิธีการที่ไม่เสมือนโดยค่าเริ่มต้นใน C ++ มีอิทธิพลต่อ C #

2-การมีทุกวิธีเสมือนโดยค่าเริ่มต้นเป็นปัญหาด้านประสิทธิภาพเนื่องจากการเรียกใช้เมธอดทุกครั้งต้องใช้ตารางเสมือนของวัตถุ ยิ่งไปกว่านั้นสิ่งนี้จำกัดความสามารถของคอมไพเลอร์ Just-In-Time อย่างมากในการอินไลน์เมธอดและทำการเพิ่มประสิทธิภาพประเภทอื่น ๆ

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

บางคนอาจสงสัยดังที่ Zifre กล่าวถึงเหตุใดภาษา C # จึงไม่ก้าวไปอีกขั้นและทำให้ชั้นเรียนถูกปิดผนึกโดยค่าเริ่มต้น นั่นเป็นส่วนหนึ่งของการถกเถียงทั้งหมดเกี่ยวกับปัญหาของการสืบทอดการนำไปใช้ซึ่งเป็นหัวข้อที่น่าสนใจมาก


1
ฉันจะมีคลาสที่ต้องการปิดผนึกโดยค่าเริ่มต้นด้วย จากนั้นก็จะสอดคล้องกัน
Andy

9

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

ปัญหาด้านประสิทธิภาพไม่ใช่เรื่องง่ายที่จะพูดว่า "ใช่" หรือ "ไม่" กับ เหตุผลนี้คือการคอมไพล์ Just In Time (JIT) ซึ่งเป็นการเพิ่มประสิทธิภาพรันไทม์ใน C #

อีกคำถามที่คล้ายกันเกี่ยวกับ " ความเร็วของการโทรเสมือน .. "


ฉันค่อนข้างสงสัยว่าวิธีการเสมือนมีผลกระทบต่อประสิทธิภาพสำหรับ C # เนื่องจากคอมไพเลอร์ JIT นั่นเป็นหนึ่งในพื้นที่ที่ JIT สามารถทำได้ดีกว่าการคอมไพล์ออฟไลน์เนื่องจากสามารถเรียกฟังก์ชันแบบอินไลน์ซึ่ง "ไม่ทราบ" ก่อนรันไทม์
David Cournapeau

1
จริงๆแล้วฉันคิดว่ามันได้รับอิทธิพลจาก Java มากกว่า C ++ ซึ่งเป็นค่าเริ่มต้น
Mehrdad Afshari

5

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

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


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

2

หากวิธีการ C # ทั้งหมดเป็นเสมือน vtbl จะใหญ่กว่ามาก

อ็อบเจ็กต์ C # มีเมธอดเสมือนหากคลาสมีการกำหนดเมธอดเสมือน เป็นความจริงที่ว่าอ็อบเจ็กต์ทั้งหมดมีข้อมูลประเภทที่มีค่าเทียบเท่า vtbl แต่หากไม่มีการกำหนดเมธอดเสมือนจะมีเพียงเมธอดของอ็อบเจ็กต์พื้นฐานเท่านั้น

@ Tom Hawtin: น่าจะถูกต้องกว่าที่จะบอกว่า C ++, C # และ Java ล้วนมาจากภาษาตระกูล C :)


1
เหตุใดจึงจะเป็นปัญหาสำหรับ vtable ที่ใหญ่กว่ามาก? มีเพียง 1 vtable ต่อคลาส (ไม่ใช่ต่ออินสแตนซ์) ดังนั้นขนาดของมันจึงไม่แตกต่างกันมากนัก
Gravity

1

มาจากพื้นหลัง perl ฉันคิดว่า C # ปิดผนึกการลงโทษของนักพัฒนาทุกคนที่อาจต้องการขยายและปรับเปลี่ยนพฤติกรรมของคลาสพื้นฐานผ่านวิธีการที่ไม่ใช่เสมือนโดยไม่บังคับให้ผู้ใช้ทุกคนในคลาสใหม่ตระหนักถึงเบื้องหลังที่อาจเกิดขึ้น รายละเอียด.

พิจารณาวิธีการเพิ่มคลาส List จะเป็นอย่างไรหากนักพัฒนาต้องการอัปเดตฐานข้อมูลที่เป็นไปได้หลายฐานข้อมูลเมื่อใดก็ตามที่รายการใดรายการหนึ่งถูก 'เพิ่ม' หาก 'เพิ่ม' เป็นเสมือนโดยค่าเริ่มต้นนักพัฒนาสามารถพัฒนาคลาส 'BackedList' ที่ลบล้างเมธอด 'เพิ่ม' ได้โดยไม่ต้องบังคับให้รหัสไคลเอนต์ทั้งหมดรู้ว่าเป็น 'BackedList' แทนที่จะเป็น 'รายการ' ปกติ สำหรับวัตถุประสงค์ในทางปฏิบัติทั้งหมด 'BackedList' สามารถดูเป็นเพียง 'รายการ' อื่นจากรหัสไคลเอนต์

สิ่งนี้สมเหตุสมผลจากมุมมองของคลาสหลักขนาดใหญ่ซึ่งอาจให้การเข้าถึงคอมโพเนนต์รายการอย่างน้อยหนึ่งรายการซึ่งตัวเองได้รับการสนับสนุนโดยสคีมาอย่างน้อยหนึ่งรายการในฐานข้อมูล เนื่องจากวิธีการ C # ไม่ใช่เสมือนโดยค่าเริ่มต้นรายการที่จัดเตรียมโดยคลาสหลักจึงไม่สามารถเป็น IEnumerable หรือ ICollection หรือแม้แต่อินสแตนซ์ List ได้ แต่ต้องโฆษณาให้ไคลเอ็นต์เป็น 'BackedList' แทนเพื่อให้แน่ใจว่าเวอร์ชันใหม่ ของการดำเนินการ "เพิ่ม" ถูกเรียกให้อัปเดตสคีมาที่ถูกต้อง


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

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

ฉันคิดว่าฉันเข้าใจประเด็นของคุณ แต่ในตัวอย่างที่เป็นรูปธรรม: 'BackedList' สามารถใช้อินเทอร์เฟซ 'IList' ได้และลูกค้าเท่านั้นที่รู้เกี่ยวกับอินเทอร์เฟซ ขวา? ฉันพลาดอะไรไปรึเปล่า? อย่างไรก็ตามฉันเข้าใจประเด็นที่กว้างขึ้นที่คุณพยายามทำ
Vetras

0

ไม่ใช่ปัญหาด้านประสิทธิภาพอย่างแน่นอน ล่าม Java ของ Sun ใช้รหัสเดียวกันในการส่ง ( invokevirtualbytecode) และ HotSpot จะสร้างรหัสเดียวกันfinalทุกประการไม่ว่าจะเป็นหรือไม่ก็ตาม ฉันเชื่อว่าอ็อบเจ็กต์ C # ทั้งหมด (แต่ไม่ใช่โครงสร้าง) มีเมธอดเสมือนดังนั้นคุณจะต้องมีการvtblระบุคลาส / รันไทม์เสมอ C # เป็นภาษาถิ่นของ "ภาษาที่เหมือน Java" เพื่อแนะนำว่ามาจาก C ++ นั้นไม่ตรงไปตรงมาอย่างสิ้นเชิง

มีความคิดว่าคุณควร "ออกแบบเพื่อการสืบทอดหรือห้ามมิฉะนั้น" ซึ่งดูเหมือนจะเป็นความคิดที่ดีในขณะที่คุณมีกรณีทางธุรกิจที่รุนแรงที่จะต้องแก้ไขอย่างรวดเร็ว บางทีอาจสืบทอดมาจากรหัสที่คุณไม่ได้ควบคุม


Hotspot ถูกบังคับให้ใช้ความยาวมากเพื่อทำการเพิ่มประสิทธิภาพนั้นอย่างแม่นยำเนื่องจากวิธีการทั้งหมดเป็นเสมือนตามค่าเริ่มต้นซึ่งมีผลกระทบต่อประสิทธิภาพอย่างมาก CoreCLR สามารถบรรลุประสิทธิภาพที่ใกล้เคียงกันในขณะที่ง่ายกว่ามาก
Yair Halberstadt

@YairHalberstadt Hotspot ต้องสามารถสำรองโค้ดที่คอมไพล์ได้ด้วยเหตุผลอื่น ๆ เป็นเวลาหลายปีแล้วที่ฉันได้ดูแหล่งที่มา แต่ความแตกต่างระหว่างวิธีการfinalและfinalวิธีที่มีประสิทธิภาพนั้นไม่สำคัญ นอกจากนี้ยังเป็นที่น่าสังเกตว่าสามารถทำการซับในแบบ bimorphic ซึ่งเป็นวิธีการแบบอินไลน์ที่มีการใช้งานสองแบบที่แตกต่างกัน
Tom Hawtin - แทคไลน์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.