เหตุใดจึงไม่สามารถโอเวอร์โหลดตัวดำเนินการผสมใน C # ได้


11

ชื่อจะทำให้เข้าใจผิดดังนั้นโปรดอ่านคำถามทั้งหมด :-)

โดย "ผู้ประกอบการที่ได้รับมอบหมายสารประกอบ" ผมมีในใจสร้างเช่นนี้ยกตัวอย่างเช่นop= +=ตัวดำเนินการกำหนดค่าบริสุทธิ์ ( =) ไม่ได้อยู่ในคำถามของฉัน

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

ฉันงงงวยด้วยความไม่สมดุลที่พบใน C ++ และ C # ( ใช่ฉันรู้ว่า C # ไม่ใช่ C ++ 2.0 ) - ใน C ++ คุณต้องโอเวอร์โหลดโอเปอเรเตอร์+=แล้วเขียน+ตัวดำเนินการที่เหมาะสมโดยอัตโนมัติอาศัยโอเปอเรเตอร์ที่กำหนดไว้ก่อนหน้านี้ ใน C # เป็นแบบย้อนกลับ - คุณโอเวอร์โหลด+และ+=สังเคราะห์สำหรับคุณ

หากฉันไม่เข้าใจผิดวิธีการในภายหลังจะฆ่าโอกาสในการปรับให้เหมาะสมในกรณีของจริง+=เนื่องจากต้องสร้างวัตถุใหม่ ดังนั้นจะต้องมีข้อได้เปรียบที่ยิ่งใหญ่ของวิธีการดังกล่าว แต่ MSDN อายเกินกว่าจะบอกได้

และฉันสงสัยว่าข้อได้เปรียบนั้นคืออะไร - ดังนั้นหากคุณเห็นคำอธิบายในหนังสือ C #, วิดีโอพูดคุยทางเทคนิค, รายการบล็อก, ฉันจะขอบคุณสำหรับการอ้างอิง

สิ่งที่ใกล้เคียงที่สุดที่ฉันพบคือความคิดเห็นในบล็อก Eric Lippert เพราะเหตุใดตัวดำเนินการโอเวอร์โหลดจึงคงที่เสมอใน C # โดย Tom Brown ถ้าการโอเวอร์โหลดแบบสแตติกถูกตัดสินก่อนสิ่งนั้นจะกำหนดเพียงว่าตัวดำเนินการใดที่สามารถโอเวอร์โหลดสำหรับโครงสร้างได้ สิ่งนี้เพิ่มเติมกำหนดสิ่งที่สามารถโอเวอร์โหลดสำหรับคลาสได้


3
คุณมีลิงค์สำหรับสไตล์ C ++ ใหม่หรือไม่? ไร้เดียงสาการบรรทุกเกินพิกัด+=ครั้งแรกดูเหมือนว่าไร้สาระ; เหตุใดคุณจึงโอเวอร์โหลดการดำเนินการแบบรวมมากกว่าส่วนของมัน
Telastyn

1
ฉันเชื่อว่าคำเหล่านี้คือ "ตัวดำเนินการมอบหมายผสม"
Ixrec

2
@greenoldman Telastyn อาจหมายความว่าการใช้ + = ในแง่ของ + ดูเหมือนเป็นธรรมชาติมากกว่าวิธีอื่น ๆ เนื่องจาก semantically + = เป็นองค์ประกอบของ + และ = เพื่อความรู้ที่ดีที่สุดของฉันการมี + call + = เป็นวิธีการเพิ่มประสิทธิภาพส่วนใหญ่
Ixrec

1
@Ixrec: บางครั้ง a + = b สมเหตุสมผลในขณะที่ a = a + b ไม่ได้พิจารณาว่าตัวตนนั้นอาจมีความสำคัญ A ไม่สามารถทำซ้ำได้ บางครั้ง a = a + b เข้าท่าในขณะที่ a = = b ไม่พิจารณาพิจารณาสายที่ไม่เปลี่ยนรูป ดังนั้นหนึ่งจริง ๆ แล้วต้องการความสามารถในการตัดสินใจที่หนึ่งเกินพิกัดแยกกัน แน่นอนว่าการสร้างสิ่งที่ขาดหายไปโดยอัตโนมัติหากมีสิ่งปลูกสร้างบล็อคที่จำเป็นทั้งหมดและมันไม่ได้ปิดใช้งานอย่างชัดเจนเป็นความคิดที่ดี ไม่ใช่ C # ที่อนุญาต atm, afaik
Deduplicator

4
@greenoldman - ฉันเข้าใจแรงบันดาลใจนั้น แต่โดยส่วนตัวแล้วฉันพบว่าการ*=กลายพันธุ์ของประเภทอ้างอิงไม่ถูกต้องในเชิงความหมาย
Telastyn

คำตอบ:


12

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

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


ขอบคุณถ้าคุณไม่รังเกียจฉันจะเก็บคำถามนี้ไว้นานกว่านี้และหากไม่มีใครเอาชนะคุณด้วยเหตุผลของการออกแบบจริงฉันจะปิดมันด้วยการยอมรับของคุณ อีกครั้ง - ขอบคุณ
greenoldman

@greenoldman - เช่นกันคุณควร ฉันก็หวังว่าจะมีใครบางคนมาพร้อมคำตอบที่เป็นรูปธรรมมากกว่า
Telastyn

ดังนั้นนี่คือสถานที่ที่เป็นไปไม่ได้ที่จะพูดถึงทั้งตัวชี้และตัวชี้อย่างสบาย ๆ ความอัปยศ
Deduplicator

"ผู้คนยืนยันว่ามันทำให้งงงวยรหัส" - มันยังคงเป็นจริงแม้ว่าคุณเคยเห็นห้องสมุด F # บ้างไหม? เสียงผู้ประกอบการ เช่นquanttec.com/fparsec
Den
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.