ทำไม“ ใช้ระบบ” ไม่ถือว่าเป็นการปฏิบัติที่ไม่ดี?


47

ฉันมีพื้นหลัง C ++ และฉันเข้าใจและเห็นด้วยอย่างยิ่งกับคำตอบของคำถามนี้: เหตุใด“ ใช้ namespace std;” ถือว่าเป็นการปฏิบัติที่ไม่ดี?

ดังนั้นฉันประหลาดใจที่มีประสบการณ์กับ C # ตอนนี้ฉันเห็นตรงข้ามแน่นอน: using Some.Namespace;มีการใช้อักษรทุกที่ เมื่อใดก็ตามที่คุณเริ่มใช้ประเภทคุณเพิ่มคำสั่งที่ใช้สำหรับเนมสเปซก่อน (ถ้ายังไม่มีอยู่) ฉันไม่สามารถจำได้เห็น.csแฟ้ม: using System; using System.Collections.Generic; using X.Y.Z; etc...ที่ไม่ได้เริ่มต้นด้วย ในความเป็นจริงถ้าคุณเพิ่มไฟล์ใหม่ผ่านวิซาร์ด Visual Studio มันจะเพิ่มไฟล์บางไฟล์โดยใช้คำสั่งที่นั่นแม้ว่าคุณอาจไม่ต้องการมันก็ตาม ดังนั้นในขณะที่ในชุมชน C ++ คุณจะได้รับการลงโทษโดยทั่วไป C # ก็สนับสนุนให้ทำเช่นนี้ อย่างน้อยนี่คือสิ่งที่ฉันเห็น

ตอนนี้ฉันเข้าใจแล้วว่าการใช้คำสั่งใน C # และ C ++ ไม่ใช่สิ่งเดียวกัน นอกจากนี้ฉันจะเข้าใจว่าหนึ่งในสิ่ง nastiest ที่คุณสามารถทำอะไรกับusing namespaceใน C ++ คือวางไว้ในไฟล์ส่วนหัวที่ไม่มีค่าเท่าคู่ที่น่ารังเกียจใน C # #includeเนื่องจากการขาดของแนวคิดของไฟล์ส่วนหัวและ

อย่างไรก็ตามแม้จะมีความแตกต่างกันก็ตามการใช้คำสั่งใน C # และ C ++ มีจุดประสงค์เดียวกันซึ่งจะต้องพิมพ์SomeTypeตลอดเวลาแทนที่จะใช้นานกว่านั้นSome.Namespace.SomeType(ใน C ++ ด้วย::แทนที่จะเป็น.) และด้วยจุดประสงค์เดียวกันนี้อันตรายก็เหมือนกันกับฉัน: การตั้งชื่อการชน

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

ความคิดบางอย่างของคำตอบที่ฉันมี (ไม่มีสิ่งเหล่านี้ทำให้ฉันพึงพอใจจริงๆ):

  • เนมสเปซมีแนวโน้มที่จะยาวและซ้อนกันมากขึ้นใน C # มากกว่าใน C ++ ( stdเทียบกับSystem.Collection.Generic) ดังนั้นจึงมีความต้องการมากขึ้นและได้รับมากขึ้นในการขจัดรหัสด้วยวิธีนี้ แต่แม้ว่าสิ่งนี้จะเป็นจริงการโต้แย้งนี้จะใช้เฉพาะเมื่อเราดูเนมสเปซมาตรฐาน Custom สามารถมีชื่อย่อใด ๆ ที่คุณชอบทั้งใน C # และ C ++

  • ดูเหมือนว่าเนมสเปซมี "ละเอียดละเอียดมาก" ใน C # มากกว่าใน C ++ ตัวอย่างเช่นใน C ++ ห้องสมุดมาตรฐานทั้งหมดที่มีอยู่ในstd(บวกบาง namespaces ซ้อนกันเล็ก ๆ ชอบchrono) ในขณะที่ใน C # คุณมีSystem.IO, System.Threading, System.Textฯลฯ ดังนั้นความเสี่ยงของการมีการชนกันตั้งชื่อมีขนาดเล็ก อย่างไรก็ตามนี่เป็นเพียงความรู้สึก ฉันไม่ได้จริงนับจำนวนชื่อคุณ "นำเข้า" กับและusing namespace std using Systemและอีกครั้งแม้ว่านี่จะเป็นจริงอาร์กิวเมนต์นี้ใช้เฉพาะเมื่อดูเนมสเปซมาตรฐาน คนของคุณสามารถออกแบบได้อย่างละเอียดตามที่คุณต้องการทั้งใน C # และ C ++

มีข้อโต้แย้งมากกว่านี้ไหม? ฉันสนใจข้อเท็จจริงที่ยากจริง ๆ (ถ้ามี) โดยเฉพาะและไม่ค่อยมีความคิดเห็น


2
@Timo The OP ไม่ได้ถามเกี่ยวกับมลพิษส่วนหัว
Konrad Rudolph

1
ฉันคิดว่ามันเป็นเพราะไม่มีการแข่งขันสำหรับ namespace ทั่วโลกในระดับเดียวกับที่มีใน C ++ (ส่วนใหญ่เนื่องจากไลบรารีมาตรฐาน C) แต่ฉันรอคำตอบของผู้รู้ดีที่สุด
Wyck

2
@ThomasWeller ใน C ++ มันชัดเจน ใน C # พิจารณาวิธีการที่ส่วนขยายกับที่เรียกว่าผ่านExt(this T t, long l) t.Ext(0)หากคุณเพิ่มเนมสเปซอื่นที่มีเมธอดส่วนขยายExt(this T t, int i)แอปนั้นจะถูกเรียกแทน แต่ฉันไม่ใช่ผู้เชี่ยวชาญใน C # (ยัง)
sebrockm

2
@Franck แม้ว่าฉันจะให้คุณจุดนั้นอาร์กิวเมนต์เดียวกันใช้กับ C ++ ต่อไปผลักดันคำถามของฉันที่ไม่เห็นความแตกต่างระหว่าง C ++ และ C #
sebrockm

3
@Franck C ++ จะโยนข้อผิดพลาดคอมไพเลอร์มาที่คุณในกรณีที่มีความกำกวม เช่นเดียวกับ C #
Timo

คำตอบ:


28

ทำไม“ ใช้ระบบ” ไม่ถือว่าเป็นการปฏิบัติที่ไม่ดี?

"ใช้ระบบ;" จะไม่ได้ในระดับสากลไม่ถือว่าการปฏิบัติที่ไม่ดี ดูตัวอย่าง: ทำไมคุณไม่ใช้คำสั่ง 'using' ใน C #

แต่มันอาจเป็นจริงได้ว่ามันไม่ถือว่าแย่พอusing namespace stdๆ อาจเป็นเพราะ:

  1. C # ไม่มีไฟล์ส่วนหัว เป็นเรื่องปกติที่จะ "รวม" ซอร์สไฟล์ C # หนึ่งไฟล์ลงในไฟล์อื่นโดยใช้ตัวประมวลผลล่วงหน้า

  2. stdเนมสเปซใกล้เคียงกันกล่าวคือเกือบทุกฟังก์ชันไลบรารีมาตรฐานชนิดและตัวแปรอยู่ในนั้น (มีข้อยกเว้นบางประการเช่นระบบย่อยย่อยของระบบแฟ้ม) มันมีตัวระบุจำนวนมากมาก เพื่อความเข้าใจของฉัน Systemมีชื่อน้อยลงและมี sub-namespaces มากขึ้นแทน

  3. ใน C # ไม่มีฟังก์ชั่นหรือตัวแปรทั่วโลก ด้วยเหตุนี้จำนวนตัวระบุทั่วโลกจึงค่อนข้างเล็กเมื่อเทียบกับ C ++ ซึ่งมี: นอกจากนี้ยังเป็นเรื่องปกติที่จะใช้ไลบรารี C (มักทางอ้อม) ซึ่งไม่มีเนมสเปซและวางชื่อทั้งหมดไว้ในโลก namespace

  4. เท่าที่ฉันรู้ C # ไม่มีการค้นหาขึ้นอยู่กับการโต้แย้ง ADL ร่วมกับการซ่อนชื่อ, การโหลดมากเกินไปเป็นต้นสามารถสร้างกรณีที่บางโปรแกรมไม่ได้รับผลกระทบจากความขัดแย้งของชื่อในขณะที่คนอื่น ๆ ได้รับผลกระทบอย่างละเอียดและการจับกรณีมุมทั้งหมดไม่เป็นไปได้กับการทดสอบ

เนื่องจากความแตกต่างเหล่านี้“ ใช้ระบบ” using namespace stdมีโอกาสลดลงของความขัดแย้งชื่อกว่า


นอกจากนี้เนมสเปซ "การอิมพอร์ต" ยังเป็นแบบแผนของการขยายเวลาด้วยตนเอง: หากเป็นแบบดั้งเดิมที่จะนำเข้าเนมสเปซมาตรฐานจากนั้นโปรแกรมเมอร์จะพยายามหลีกเลี่ยงการเลือกชื่อจากเนมสเปซนั้นตามอัตภาพของตนเอง การประชุมดังกล่าว

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


3
สิ่งนี้จะพิจารณาข้อเสียที่เป็นไปได้ของการเปิดเนมสเปซเท่านั้น นั่นเป็นจุดเริ่มต้น แต่ฉันคิดว่าเราจำเป็นต้องพิจารณาถึงข้อดี: ในกรณีของ C ++ ในกรณีส่วนใหญ่จะเป็นการประหยัดอักขระห้าตัว ( std::) ใน C # มันมีความหมายมากกว่า ( System.มี“ เพียง” 7 ตัวอักษร แต่เนมสเปซที่ซ้อนกันอื่น ๆ มีอักขระอีกหลายตัวและการเขียนออกมาทุกที่จะทำให้โค้ดอ่านไม่ได้อย่างสมบูรณ์)
Konrad Rudolph

ไม่เช่นนั้น C # ความละเอียดเกินพิกัดจะดีกว่าใน C ++ และความคลุมเครือจำนวนมากถูกดึงออกมาจากข้อผิดพลาดของคอมไพเลอร์? (ไม่ได้เป็นการวิจารณ์คำตอบของคุณซึ่งน่าเชื่อถือ)
Bathsheba

3
@KonradRudolph หากมีการพิจารณาข้อเสียอย่างมีนัยสำคัญและปริมาณการพิมพ์เท่ากันดังนั้น (เทียบกับจำนวนการพิมพ์std::) มันจะไม่เป็นรูปแบบทั่วไปที่จะใช้using Sys = System;แทนเนมสเปซที่ทำให้เกิดมลพิษไม่ใช่นามแฝงusing?
eerorika

2
@Bathsheba เกี่ยวกับ "เผด็จการ" ฉันขอปฏิเสธว่าฉันรู้เกี่ยวกับ C # น้อยมากและคำตอบของฉันนั้นขึ้นอยู่กับความรู้เกี่ยวกับ C ++ และการค้นหาของ Google เกี่ยวกับ C # ดังนั้นฉันจึงอยากขอให้ตรวจสอบความเป็นจริงคนที่ C # ส่วน :)
eerorika

2
เกี่ยวกับส่วน ADL: C # มีวิธีการขยาย มันเป็นการออกแบบที่แตกต่างจาก ADL แต่พวกเขาแบ่งปันปัญหาเดียวกันเกี่ยวกับการตั้งชื่อความขัดแย้ง
Timo

-2

อย่างไรก็ตามแม้จะมีความแตกต่างกันก็ตามการใช้คำสั่งใน C # และ C ++ ให้บริการเพื่อจุดประสงค์เดียวกันซึ่งจะต้องพิมพ์ SomeType ตลอดเวลาแทนที่จะใช้ Some.Namespace.SomeType (ใน C ++ กับ :: แทน.) ที่ยาวกว่ามาก และด้วยจุดประสงค์เดียวกันนี้อันตรายก็เหมือนกันกับฉัน: การตั้งชื่อการชน

ใช่ แต่คุณไม่ได้ส่งออกอันตรายนั้น (อ่าน: บังคับให้ผู้อื่นจัดการกับมัน) เนื่องจาก:

ตอนนี้ฉันเข้าใจแล้วว่าการใช้คำสั่งใน C # และ C ++ ไม่ใช่สิ่งเดียวกัน นอกจากนี้ฉันเข้าใจว่าหนึ่งในสิ่งที่น่ารังเกียจที่สุดที่คุณสามารถทำได้ด้วยการใช้เนมสเปซใน C ++ คือใส่ไว้ในไฟล์ส่วนหัวไม่เทียบเท่าใน C # เนื่องจากไม่มีแนวคิดของไฟล์ส่วนหัวและ #include

ดังนั้นมันจึงเป็นหมวดหมู่ที่แตกต่างออกไป

นอกจากนี้ C ++ ไม่ใช่ "ออกแบบ" ที่จะพัฒนาใน IDE แบบเดียวกับ C # โดยทั่วไปแล้ว C # จะเขียนด้วย Visual Studio พร้อม Intellisense และอะไรก็ตาม มันถูกออกแบบมาเพื่อใช้ในวิธีนั้นโดยคนที่สร้างมันขึ้นมา ไม่ว่าจะมีคนจำนวนเท่าใดที่ใช้ IDE เพื่อพัฒนาใน C ++ มันไม่ได้ถูกออกแบบด้วยกรณีการใช้งานนั้น ๆ

ดูเหมือนว่าเนมสเปซมี "ละเอียดละเอียดมาก" ใน C # มากกว่าใน C ++

ใช่เช่นกัน using namespace stdและusing System.Collection.Genericหาที่เปรียบมิได้

ดังนั้นอย่าเปรียบเทียบมัน!


2
นี้ไม่ได้ตอบความกังวลของ OP ซึ่งเป็นอย่างชัดเจนไม่ได้เกี่ยวกับการเปิด namespaces ในหัว แต่ในไฟล์การดำเนินงาน
Konrad Rudolph

2
@KonradRudolph คำแนะนำในการหลีกเลี่ยงusing namespace stdใน C ++ นั้นส่วนใหญ่เกี่ยวกับไฟล์ส่วนหัว คำตอบคือสิ่งนี้ไม่สามารถใช้ได้ใน C #
ดาวเคราะห์น้อยที่มีปีก

8
@Asteroids ด้วยคำแนะนำในการหลีกเลี่ยงusing namespace stdไม่ได้เกี่ยวกับส่วนหัวแน่นอน การใช้ในส่วนหัวเป็นสิ่งที่อันตราย แนะนำให้ใช้ในการใช้งานของคุณ
Tommy Andersen

1
คำแนะนำในการหลีกเลี่ยงusing namespace ...ใน c ++ นั้นเกี่ยวกับการหลีกเลี่ยงการชนกันของการตั้งชื่อusingคำสั่งใน C # นำเสนอความเป็นไปได้ของการตั้งชื่อการชนเช่นกันดังนั้นทำไมไม่หลีกเลี่ยง แม้ว่าจะมีการใช้งานที่แตกต่างกัน
Tommy Andersen

@TommyAndersen มันยากแค่ไหนที่จะแก้ไขความขัดแย้งดังกล่าวถ้ามันเกิดขึ้น? ใช้เวลาไม่กี่วินาที เนื่องจากusingการประกาศC # เป็นแบบต่อไฟล์ที่กำหนดประเภท / คลาสเดียวและประเภทปกติเกี่ยวข้องกับชุดโดเมนแนวคิดแอปพลิเคชันที่ค่อนข้างแคบ แต่เมื่อเกิดขึ้นสามารถแก้ไขได้อย่างง่ายดาย เครื่องมือพัฒนา. NET ทั่วไป / IDE ช่วยคุณได้มากด้วย พิจารณาระบบนิเวศการพัฒนาทั้งหมดที่ออกแบบมาเพื่อให้คุณมีประสิทธิผลมากขึ้นโดยรวมสิ่งที่ดีที่สุดของกิจกรรมการพัฒนาหลายอย่างไว้ด้วยกัน
AKornich
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.