ทำไมคุณไม่ใช้คำสั่ง 'use' ใน C #


71

มาตรฐานการเข้ารหัสที่มีอยู่ในโครงการ C # ขนาดใหญ่มีกฎที่ชื่อประเภททั้งหมดมีคุณสมบัติครบถ้วนโดยห้ามใช้คำสั่ง 'การใช้' ดังนั้นแทนที่จะคุ้นเคย:

using System.Collections.Generic;

.... other stuff ....

List<string> myList = new List<string>();

(อาจไม่แปลกใจที่varห้ามใช้เช่นกัน)

ท้ายที่สุดฉัน:

System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();

นั่นคือการเพิ่มขึ้นของการพิมพ์ 134% โดยไม่มีการเพิ่มที่ให้ข้อมูลที่เป็นประโยชน์ ในมุมมองของฉันการเพิ่มขึ้น 100% คือเสียง (ความยุ่งเหยิง) ที่ขัดขวางการทำความเข้าใจ

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

คุณเคยได้ยินเกี่ยวกับมาตรฐานดังกล่าวหรือไม่? ถ้าเป็นเช่นนั้นอะไรคือเหตุผลที่อยู่เบื้องหลัง คุณนึกถึงข้อโต้แย้งอื่น ๆ ที่ไม่ใช่ "มันโง่" หรือ "คนอื่นทุกคนusing" ซึ่งอาจโน้มน้าวให้บุคคลนี้ลบข้อห้ามนี้ได้หรือไม่?

เหตุผล

เหตุผลในการห้ามนี้คือ:

  1. เป็นเรื่องยุ่งยากที่จะวางเมาส์เหนือชื่อเพื่อให้ได้ชนิดที่ผ่านการรับรองโดยสมบูรณ์ มันจะดีกว่าที่จะมีประเภทที่มีคุณสมบัติครบถ้วนมองเห็นได้ตลอดเวลา
  2. ตัวอย่างโค้ดที่ส่งทางอีเมลนั้นไม่มีชื่อที่ผ่านการรับรองดังนั้นจึงเป็นเรื่องยากที่จะเข้าใจ
  3. เมื่อดูหรือแก้ไขรหัสด้านนอกของ Visual Studio (ตัวอย่างเช่น Notepad ++) เป็นไปไม่ได้ที่จะได้รับชื่อประเภทที่ผ่านการรับรองโดยสมบูรณ์

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

ปัญหาความขัดแย้งของเนมสเปซที่เป็นไปได้ซึ่งฉันคาดว่าจะเป็นข้อกังวลหลักไม่ได้กล่าวถึง มันน่าประหลาดใจเป็นพิเศษเพราะเรามีเนมสเปซMyCompany.MyProject.Coreซึ่งเป็นความคิดที่ไม่ดีเป็นพิเศษ ฉันเรียนรู้มานานแล้วว่าการตั้งชื่ออะไรSystemหรือCoreใน C # เป็นเส้นทางที่รวดเร็วไปสู่ความวิกลจริต

ตามที่คนอื่น ๆ ได้ชี้ให้เห็นความขัดแย้งของเนมสเปซจะได้รับการจัดการอย่างง่ายดายโดยการเปลี่ยนโครงสร้างชื่อแทนเนมสเปซหรือการรับรองบางส่วน


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
maple_shaft

1
ตัวอย่างในโลกแห่งความเป็นจริงว่าทำไมจึงเป็นความคิดที่ดี (แต่ในโลก C ++): คำตอบสำหรับเหตุใด“ การใช้เนมสเปซ std;” ถือว่าเป็นแนวปฏิบัติที่ไม่ดี? ใกล้ "ที่คำสั่ง 'ใช้' และการประกาศถูกห้าม"
Peter Mortensen

ก่อนที่จะอ่านหัวข้อการใช้เหตุผลฉันเดาสาเหตุที่ไม่ได้ผลเพราะ บริษัท ของฉันมีกฎที่คล้ายกัน
Gqqnbig

คำตอบ:


69

คำถามที่กว้างขึ้น:

คุณเคยได้ยินเกี่ยวกับมาตรฐานดังกล่าวหรือไม่? ถ้าเป็นเช่นนั้นอะไรคือเหตุผลที่อยู่เบื้องหลัง

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


ตัวอย่าง: สถานการณ์ประเภทนั้นน่าจะอธิบายได้ดีกว่าด้วยตัวอย่าง

สมมติว่าเรามีสองโครงการLists<T>ที่เป็นของสองโครงการ

System.Collections.Generic.List<T>
MyCorp.CustomCollections.Optimized.List<T>

เมื่อเราใช้ชื่อออบเจ็กต์ที่ผ่านการรับรองอย่างสมบูรณ์จะเห็นได้ชัดว่าList<T>กำลังใช้งานอะไรอยู่ ความชัดเจนนั้นมาจากต้นทุนของการใช้คำฟุ่มเฟือย

และคุณอาจโต้เถียงว่า "เดี๋ยวก่อน! ไม่มีใครจะใช้สองรายการแบบนั้น!" สิ่งใดที่ฉันจะชี้ให้เห็นสถานการณ์การบำรุงรักษา

คุณกำลังเขียนโมดูลFooสำหรับ บริษัท ของคุณซึ่งใช้ บริษัท List<T>ที่ได้รับการอนุมัติการเพิ่มประสิทธิภาพ

using MyCorp.CustomCollections.Optimized;

public class Foo {
    List<object> myList = ...;
}

ในภายหลังผู้พัฒนารายใหม่ตัดสินใจที่จะขยายงานที่คุณทำ ไม่ทราบถึงมาตรฐานของ บริษัท พวกเขาอัปเดตusingบล็อก:

using MyCorp.CustomCollections.Optimized;
using System.Collections.Generic;

และคุณสามารถเห็นว่าสิ่งต่าง ๆ เป็นไปอย่างรวดเร็ว

ควรชี้ให้เห็นว่าคุณอาจมีคลาสที่เป็นกรรมสิทธิ์สองชื่อที่เหมือนกัน แต่ในเนมสเปซที่ต่างกันภายในโครงการเดียวกัน ดังนั้นจึงไม่ใช่แค่ความกังวลเกี่ยวกับการชนกับ. NET framework ที่จัดหาให้

MyCorp.WeightsAndLengths.Measurement();
MyCorp.TimeAndSpace.Measurement();

ความจริง:
ตอนนี้สิ่งนี้น่าจะเกิดขึ้นในโครงการส่วนใหญ่หรือไม่? ไม่ไม่ได้จริงๆ แต่เมื่อคุณทำงานในโครงการขนาดใหญ่ที่มีอินพุตจำนวนมากคุณทำอย่างดีที่สุดเพื่อลดโอกาสที่สิ่งต่าง ๆ จะระเบิดใส่คุณ

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

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


ทางเลือก:
ในขณะที่คุณไม่ได้ถามก็คุ้มค่าที่ชี้ให้เห็นว่านี่คือไม่ได้เป็นทางออกที่ดีในการแก้ไขปัญหา ไม่ใช่ความคิดที่ดีที่จะสร้างคลาสที่จะชนกันโดยไม่มีการประกาศเนมสเปซ

List<T>โดยเฉพาะอย่างยิ่งควรถือว่าเป็นคำสงวนและไม่ใช้เป็นชื่อสำหรับชั้นเรียนของคุณ

เช่นเดียวกันเนมสเปซแต่ละรายการภายในโครงการควรพยายามมีชื่อคลาสที่ไม่ซ้ำกัน ต้องลองและจำชื่อที่Foo()คุณกำลังทำงานกับnamespace ที่เป็นค่าใช้จ่ายทางจิตที่หลีกเลี่ยงที่ดีที่สุด กล่าวอีกวิธีหนึ่งคือการมีMyCorp.Bar.Foo()และMyCorp.Baz.Foo()กำลังจะไปพัฒนานักพัฒนาของคุณและหลีกเลี่ยงที่ดีที่สุด

หากไม่มีอะไรอื่นคุณสามารถใช้เนมสเปซบางส่วนเพื่อแก้ไขความกำกวม ตัวอย่างเช่นหากคุณไม่สามารถเปลี่ยนชื่อFoo()คลาสได้คุณสามารถใช้เนมสเปซบางส่วนได้:

Bar.Foo() 
Baz.Foo()

เหตุผลเฉพาะสำหรับโครงการปัจจุบันของคุณ:

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

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

"ยุ่งยาก?" อืมไม่. อาจจะน่ารำคาญ ย้ายไม่กี่ออนซ์พลาสติกในการสั่งซื้อที่จะเปลี่ยนตัวชี้บนหน้าจอไม่ยุ่งยาก แต่ฉันเชือนแช

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

นี่ไม่ใช่เหตุผลที่ถูกต้องสำหรับชื่อคลาสที่ผ่านการรับรองอย่างสมบูรณ์อาจเป็นเหตุผลที่ถูกต้องสำหรับการใช้ชื่อคลาสที่ผ่านการรับรองบางส่วน

ตัวอย่างโค้ดที่ส่งทางอีเมลนั้นไม่มีชื่อที่ผ่านการรับรองดังนั้นจึงเป็นเรื่องยากที่จะเข้าใจ

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

เมื่อดูหรือแก้ไขรหัสด้านนอกของ Visual Studio (ตัวอย่างเช่น Notepad ++) เป็นไปไม่ได้ที่จะได้รับชื่อประเภทที่ผ่านการรับรองโดยสมบูรณ์

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

ฉันเหลือสงสัยว่าทำไมทีมแก้ไขหรือดูรหัสนอก Visual Studio บ่อยๆ และตอนนี้เรากำลังดูเหตุผลที่ค่อนข้างฉากกับสิ่งที่ namespaces มีความหมายที่จะให้ นี่คืออาร์กิวเมนต์ที่ได้รับการสนับสนุนด้านเครื่องมือในขณะที่ namespaces อยู่ที่นั่นเพื่อจัดเตรียมโครงสร้างองค์กรให้กับโค้ด

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

ระบุว่ามีคลาสที่มีชื่อไม่ดีและสมมติว่าคุณไม่สามารถสร้างซ้ำได้คำตอบที่ถูกต้องคือการใช้ Visual Studio IDE เพื่อประโยชน์เต็มที่ อาจพิจารณาเพิ่มในปลั๊กอินเช่นแพ็คเกจ VS PowerTools จากนั้นเมื่อฉันดูที่AtrociouslyNamedClass()ฉันสามารถคลิกที่ชื่อคลาสกด F12 และนำไปสู่คำจำกัดความของคลาสโดยตรงเพื่อให้เข้าใจสิ่งที่พยายามทำดีขึ้น ในทำนองเดียวกันฉันสามารถคลิก Shift-F12 เพื่อค้นหาจุดทั้งหมดในรหัสที่กำลังใช้งานAtrociouslyNamedClass()อยู่

เกี่ยวกับข้อกังวลด้านเครื่องมือภายนอก - สิ่งที่ดีที่สุดที่ควรทำคือหยุดมันไว้ อย่าส่งตัวอย่างข้อมูลอีเมลไปๆมาๆหากไม่ชัดเจนทันทีถึงสิ่งที่อ้างอิง อย่าใช้เครื่องมืออื่นนอกเหนือจาก Visual Studio เนื่องจากเครื่องมือเหล่านั้นไม่มีสติปัญญารอบ ๆ รหัสที่ทีมของคุณต้องการ Notepad ++ เป็นเครื่องมือที่ยอดเยี่ยม แต่ก็ไม่ได้ถูกตัดออกสำหรับงานนี้

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


1
+1 ฉันยังเจอการชนกันที่น่ารังเกียจในเนมสเปซภายในของเรา ทั้งในการย้ายรหัสดั้งเดิมไปยังโครงการ "2.0" และเพียงแค่มีชื่อคลาสที่เลือกไม่กี่อันที่ถูกต้องทางความหมายในบริบทเนมสเปซที่แตกต่างกัน สิ่งที่ซับซ้อนจริงๆก็คือสองสิ่งที่มีชื่อเดียวกันมักจะมีอินเตอร์เฟสที่เหมือนกันดังนั้นคอมไพเลอร์จะไม่บ่น ... รันไทม์ของคุณจะ!
svidgen

23
ปัญหานี้แก้ไขได้ด้วยการใช้นามแฝงเนมสเปซไม่ใช่โดยการกำหนดกฎโง่ ๆ ที่ต้องใช้รหัสโดยรกด้วยการใช้เนมสเปซที่ชัดเจน
David Arno

4
@DavidArno - ฉันไม่เห็นด้วยกับคุณ อย่างไรก็ตามโครงการขนาดใหญ่อาจไม่มีตัวเลือกนั้น ฉันแค่ชี้ให้เห็นว่าทำไมโครงการขนาดใหญ่อาจกำหนดกฎนั้น แม้ว่าฉันจะไม่สนับสนุนกฎนี้ก็ตาม เพียงแค่ว่าบางครั้งก็จำเป็นเพราะทีมไม่มีตัวเลือกอื่น ๆ

4
@ GlenH7 คุณอาจต้องการระบุโซลูชันอื่น ๆ ที่มีอยู่ในคำตอบของคุณ ฉันเกลียดที่จะเห็นคนสะดุดและคิดว่า "โอ้นั่นเป็นความคิดที่ยอดเยี่ยม!" +1 สำหรับวัตถุประสงค์ที่เหลืออยู่และในทางปฏิบัติแม้ว่า
RubberDuck

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

16

ฉันทำงานที่ บริษัท แห่งหนึ่งซึ่งพวกเขามีหลายชั้นเรียนที่มีชื่อเหมือนกัน แต่ในห้องสมุดชั้นต่างๆ

ตัวอย่างเช่น,

  • Domain.Customer
  • Legacy.Customer
  • ServiceX.Customer
  • ViewModel.Customer
  • Database.Customer

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

ไม่ว่าในกรณีใดมีหลายที่ที่โปรเจ็กต์ซึ่งอ้างอิงไลบรารีที่แตกต่างกันทั้งหมดเหล่านี้จำเป็นต้องใช้คลาสหลายเวอร์ชัน

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

อย่างน้อยก็มีเนมสเปซบางส่วน

var cust = new Domain.Customer

หรือ

public void Purchase(ViewModel.Customer customer)

ปรับปรุงความสามารถในการอ่านของโค้ดได้อย่างมากและทำให้ชัดเจนว่าคุณต้องการวัตถุใด

มันไม่ใช่มาตรฐานการเข้ารหัสไม่ใช่เนมสเปซเต็มรูปแบบและไม่ได้ใช้กับคลาสทั้งหมดเป็นมาตรฐาน


13
"ทางเลือกคืออะไรเปลี่ยนชื่อคลาสทั้งหมดเพื่อรวม namespace หรือไม่ refactoring สำคัญของทุกอย่างหรือไม่" ใช่นั่นเป็นทางเลือกที่ถูกต้อง
David Arno

2
เฉพาะในระยะสั้น มันแพงน้อยกว่าการใช้เนมสเปซที่ชัดเจนในโค้ดในระยะยาว
David Arno

3
ยินดีที่จะยอมรับข้อโต้แย้งนั้นตราบใดที่คุณจ่ายเงินให้ฉันเป็นเงินสดไม่ใช่หุ้น
Ewan

8
@ David: ไม่ไม่ใช่ทางเลือกที่ถูกต้อง มีคุณสมบัติครบถ้วนทั้งตัวระบุทั้งหมดหรืออย่างน้อยที่ชนจริงเป็นวิธีที่ถูกต้องและเหตุผลที่ว่าทำไม namespaces อยู่ในสถานที่แรกคือการให้การชนกันเมื่อมีการใช้ชื่อเดียวกันในโมดูลที่แตกต่างกัน ประเด็นก็คือว่าบางส่วนของโมดูลอาจมาจากบุคคลที่สามซึ่ง codebase ที่คุณไม่สามารถแก้ไขได้ แล้วคุณจะทำอย่างไรเมื่อตัวระบุจากลิสต์ของบุคคลที่สามที่แตกต่างกันชนกันและคุณต้องใช้ทั้งสองไลบรารี่ แต่ไม่สามารถรีแฟคเตอร์ทั้งสองได้ มีเนมสเปซอยู่เนื่องจากการปรับโครงสร้างเป็นไปไม่ได้เสมอไป
Kaiserludi

4
@CarlSixsmith หากมีใครสมัครรับข้อมูลมุมมองของ Martin Fowler เกี่ยวกับการปรับโครงสร้างใหม่หากว่าการเปลี่ยนแปลงนั้นส่งผลกระทบต่อผู้ใช้แสดงว่าคุณถูกต้องแล้ว เป็นการปรับโครงสร้างอีกรูปแบบหนึ่ง สิ่งนี้ยกสองจุดแม้ว่า: 1. วิธีการแบบสาธารณะทั้งหมดเป็นส่วนหนึ่งของ API โดยอัตโนมัติหรือไม่ 2. ฟาวเลอร์ยอมรับว่าเขากำลังต่อสู้เพื่อต่อสู้กับคำจำกัดความนี้โดยมีผู้คนจำนวนมากที่ใช้คำว่า "refactoring" เพื่อหมายถึงการปรับโครงสร้างทั่วไปรวมถึงการเปลี่ยนแปลงในที่สาธารณะ
David Arno

7

ไม่มีดีที่จะ verbose หรือสั้นเกินไป: หนึ่งควรหากลางทองในรายละเอียดเพียงพอเพื่อป้องกันข้อผิดพลาดที่บอบบางในขณะที่หลีกเลี่ยงการเขียนรหัสมากเกินไป

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

if (...) throw new ArgumentNullException("name", "The name should be specified.");
if (...) throw new ArgumentException("name", "The name contains forbidden characters.");

ตั้งแต่แรกเห็นมันดูดีมาก แต่มีข้อผิดพลาด ลายเซ็นของตัวสร้างข้อยกเว้นคือ:

public ArgumentException(string message, string paramName)
public ArgumentNullException(string paramName, string message)

สังเกตเห็นคำสั่งของการขัดแย้ง?

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

if (...) throw new ArgumentNullException(paramName: "name", message: "The name should be specified.");
if (...) throw new ArgumentException(paramName: "name", message: "The name contains forbidden characters.");

เห็นได้ชัดว่ามีความยาวในการเขียน แต่ส่งผลให้การดีบักเสียเวลาน้อยลง

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

ในกรณีของคุณแรงจูงใจที่อยู่เบื้องหลัง“ไม่มีusingกฎ” คือว่ามันควรจะทำให้มันยากมากที่จะใช้ผิดประเภทเช่นเทียบกับMyCompany.Something.List<T>System.Collections.Generic.List<T>

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


สถานการณ์เช่นนี้สามารถตรวจพบได้โดยเครื่องมือ ReSharper ทำเครื่องหมายparamNameด้วยInvokerParameterNameแอ็ตทริบิวต์และออกคำเตือนหากไม่มีพารามิเตอร์ดังกล่าว
Johnbot

2
@Johnbot: พวกเขาสามารถทำได้ แต่ในบางกรณีมีจำนวน จำกัด มาก เกิดอะไรขึ้นถ้าฉันมีSomeBusiness.Something.DoStuff(string name, string description)? ไม่มีเครื่องมือที่ฉลาดพอที่จะเข้าใจชื่อและคำอธิบายอะไร
Arseni Mourzenko

@ArseniMourzenko ในกรณีนี้แม้แต่ความต้องการของมนุษย์ก็ต้องใช้เวลาในการพิจารณาว่าการร้องขอนั้นถูกต้องหรือไม่
Gqqnbig

6

เนมสเปซให้รหัสโครงสร้างแบบลำดับชั้นช่วยให้ชื่อที่สั้นกว่า

   MyCompany.Headquarters.Team.Leader
   MyCompany.Warehouse.Team.Leader

หากคุณอนุญาตให้ใช้คำหลัก "การใช้" จะมีกลุ่มของกิจกรรม ...

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

ดังนั้นเพื่อหลีกเลี่ยงความเสี่ยงทุกคนเริ่มใช้ชื่อที่ยาวมาก ๆ :

   HeadquartersTeamLeader
   WarehouseTeamLeader

สถานการณ์ทวีความรุนแรงขึ้น ...

  • คนอื่นอาจเลือกชื่อไว้แล้วดังนั้นคุณจึงใช้ชื่อที่ยาวกว่าได้
  • ชื่อยาวขึ้นเรื่อย ๆ
  • ความยาวสามารถยาวเกิน 60 ตัวอักษรโดยไม่มีความยาวสูงสุด - มันไร้สาระ

ฉันเห็นสิ่งนี้เกิดขึ้นดังนั้นสามารถเห็นอกเห็นใจกับ บริษัท ที่ห้าม "ใช้งาน"


11
การแบนusingเป็นตัวเลือกนิวเคลียร์ ชื่อแทนเนมสเปซและการรับรองบางส่วนนั้นเป็นที่นิยมมากกว่า
Jim Mischel

1

ปัญหาusingคือมันเพิ่มอย่างน่าอัศจรรย์ให้กับเนมสเปซโดยไม่ต้องประกาศอย่างชัดเจน นี่เป็นปัญหาอีกมากสำหรับโปรแกรมเมอร์บำรุงรักษาที่พบสิ่งที่ชอบList<>และไม่คุ้นเคยกับโดเมนไม่รู้ว่าusingประโยคใดที่นำมาใช้

ปัญหาที่คล้ายกันเกิดขึ้นใน Java ถ้ามีคนเขียนimport Java.util.*;มากกว่าimport Java.util.List;ตัวอย่าง; เอกสารการประกาศหลังชื่อสิ่งที่ได้รับการแนะนำเพื่อที่ว่าList<>จะเกิดขึ้นในภายหลังในแหล่งที่มาของมันเป็นที่รู้จักจากการimportประกาศ


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

จิม .. ฉันแค่ลองวางเม้าส์เหนือคำจำกัดความแล้วมันก็ไม่ทำงาน คุณได้พิจารณาถึงความเป็นไปได้ไหมที่โปรแกรมเมอร์บางคนในโลกไม่ได้ใช้ Microsoft IDEs? ไม่ว่าในกรณีใดเคาน์เตอร์ของคุณจะไม่ทำให้คะแนนของฉันเป็นโมฆะว่าแหล่งที่มาพร้อมกับการใช้งานนั้นไม่ได้จัดทำเอกสารด้วยตนเองอีกต่อไปแล้ว
Michael Montenero

2
ใช่มีคนที่ทำงานใน C # ที่เป็นผู้พิการโดยไม่ใช้เครื่องมือที่ดีที่สุด และในขณะที่ข้อโต้แย้งว่าคุณสมบัติทั้งหมดคือ "การทำเอกสารด้วยตนเอง" มีข้อดีบางประการรหัสดังกล่าวมีราคาสูงมากในการอ่าน รหัสที่ไม่เกี่ยวข้องทั้งหมดจะสร้างเสียงรบกวนซึ่งปิดบังส่วนต่าง ๆ ของรหัสที่มีความสำคัญ
Jim Mischel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.