หลักการตั้งชื่อที่ดีสำหรับประเภททั่วไปใน C # คืออะไร [ปิด]


16

ฉันตัดสินใจถามคำถามนี้ที่นี่แทนที่จะเป็นแบบล้นสแต็กเพราะมันค่อนข้างเป็นอัตนัย

ใน C # ปกติฉันเห็นประเภททั่วไปที่มีชื่อไม่ดี โดยทั่วไปมักใช้ "T" แต่ไม่ใช่ชื่อที่สื่อความหมายด้วยตัวเอง ตัวอย่างเช่น:

class Fruit<T>
{
    T fruit;
}

ในขณะที่นี่เป็นวิธีการทั่วไปใครจะแนะนำต่อต้านนี้ และถ้าเป็นเช่นนั้นแผนการตั้งชื่อที่สมเหตุสมผลจะเป็นประเภททั่วไปในบริบทของ C # สำหรับฟังก์ชันและคลาสทั่วไป

ในตัวอย่างก่อนหน้านี้สมมติว่าประเภททั่วไปTมักจะต้องเป็นชนิดของผลไม้เช่นหรือApple OrangeประเภทTต้องทำให้ชัดเจนว่าเป็นผลไม้ชนิดหนึ่งดังนั้นอาจเป็นชื่อที่ดีกว่าFruitTypeดังนั้นเราจึงจบลงด้วย:

class Fruit<FruitType>
{
    FruitType fruit;
}

นี่เป็นเพียงเพื่อให้พวกคุณได้คิดในสิ่งที่ฉันกำลังมอง "กฎง่ายๆ" ที่ยอมรับได้สำหรับปัญหานี้คืออะไร


3
นี่ไม่ใช่คำถามที่สร้างสรรค์ มันจะได้รับคำตอบด้วยสไตล์ที่ชื่นชอบของผู้โพสต์
Michael K

1
ดูข้อ จำกัด โดยพิจารณาตัวอย่างของคุณ: msdn.microsoft.com/en-us/library/d5x73970.aspx#Y426
Matthieu

2
@Michael จะมีคำตอบจำนวนมากและคำตอบที่ยอมรับจะเป็นคำตอบที่โรเบิร์ตชื่นชอบ แต่คำตอบอื่น ๆ อีกมากมายจะได้รับการโหวต
StuperUser

5
@Michael คำถามอัตนัยได้คำตอบส่วนตัว คำถามนี้ยังคงสร้างสรรค์เพราะทำหน้าที่เป็นจุดอ้างอิงสำหรับทุกคนที่ต้องการความคิด / การแก้ไขที่หลากหลายสำหรับปัญหานี้โดยเฉพาะ คำตอบที่ฉันทำเครื่องหมายว่าคำตอบไม่ได้แสดงถึงข้อมูลที่เป็นประโยชน์เพียงเล็กน้อยเท่านั้น
void.pointer

อาจทำให้มันกลายเป็นวิกิชุมชนเป็นทรัพยากรที่ดีแม้ว่าเป็นการส่วนตัวหรือไม่
tylermac

คำตอบ:


22

มันย่อมเป็นอัตนัย ... ish
เนื่องจากบางคนพบว่าiมีความถูกต้องสมบูรณ์แบบสำหรับตัวแปรลูปบางคนคิดว่าTใช้ได้อย่างสมบูรณ์แบบสำหรับตัวยึดตำแหน่งประเภทในคลาสทั่วไป

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

ประเภทที่มีความหมายฉันจะใช้ชื่อที่มีความหมาย แต่โดยทั่วไปแล้วจะเริ่มต้นด้วย T เมื่อเร็ว ๆ นี้ฉันได้พัฒนาคลาสพจนานุกรมทั่วไป (ไม่ต้องถาม) และการประกาศคือ

public class Dictionary<TKey, TValue>

อย่างไรก็ตามสำหรับบางอย่างเช่น Tuple ที่ประเภทไม่มีความหมายเป็นหลักฉันคิดว่าต่อไปนี้เป็นที่ยอมรับอย่างสมบูรณ์

public class Tuple<T1, T2, T3>

2
ฉันไม่พบสิ่งนี้เลย iและการTทำงานและสิ่งนี้สามารถวัดได้ในหลักการ (เช่นสามารถวัดได้ว่าความเข้าใจในซอร์สโค้ดเพิ่มขึ้นหรือไม่ถ้าดัชนีลูปได้รับตัวระบุต่างกัน) เพียงเพราะมันยากที่จะวัดไม่ได้หมายความว่าเราต้องติดป้ายกำกับ "อัตนัย" ในทุกสิ่ง ด้วยการใช้งานอย่างกว้างขวางโดยไม่มีปัญหาที่ชัดเจนมันค่อนข้างสมเหตุสมผลที่จะพูดแม้จะไม่มีการวัดว่านี่ใช้งานได้จริง
Konrad Rudolph

2
@ Konrad: คุณมีจุด . . อย่างไรก็ตามคำถามไม่ได้ถูกแท็กเป็นแบบอัตนัยผู้ถามยอมรับว่าเป็นหัวข้ออัตนัยหากว่าผู้คนมักจะชอบการตั้งชื่อแบบแผนของตัวเอง ดังนั้นในขณะที่คำถามอาจไม่เป็นอัตนัย (และตามความเป็นจริงมันไม่ได้เพราะมีคำตอบที่ถูกต้องเช่นคำตอบที่เชื่อมโยงไปยังแนวทางอย่างเป็นทางการของ Microsoft) หัวข้อนั้นเป็นเรื่องส่วนตัวเพราะฉันแน่ใจว่าบางคนจะโพสต์ " iและTเป็นสิ่งที่ชั่วร้ายเราจะต้องไม่ใช้ชื่อตัวอักษรเดียวเลย" พิมพ์คำตอบ ได้เพิ่มishเพื่อช่วยทำให้พอใจทุกคน :)
Binary Worrier

1
ฉันคิดว่าความคิดเห็นที่เพิ่มไว้ในโพสต์นี้เพียงอย่างเดียวทำให้เป็นคำตอบที่มีค่ามากถึงแม้ว่าคำตอบนั้นจะมีประโยชน์มาก Tสมเหตุสมผลเมื่อเรากำลังพูดถึงประเภทที่ไม่มีข้อ จำกัดTFruitทำให้สมเหตุสมผลเพราะมันบอกกับฉันว่า "ชนิดใดที่มีข้อ จำกัด ว่าเป็นผลไม้" ดูเหมือนว่า "กฎง่ายๆ" ที่ดีสำหรับการตั้งชื่อพารามิเตอร์ประเภททั่วไป ขอบคุณ !!
void.pointer

1
สิ่งที่ควรทราบคือสิ่งนี้สอดคล้องกับแนวทางการออกแบบ. NET Framework สำหรับนักพัฒนาห้องสมุดจาก MSDN ดู: รายชื่อประเภททั่วไปพารามิเตอร์
โทมัส

7

ฉันคิดว่าคุณพูดถูกแม้ว่า T กลายเป็นมาตรฐาน มันอาจมาจากครั้ง C ++ เก่าและถ้อยคำ "ของประเภท T" ฉันคิดว่ามันเป็นวิธีปฏิบัติที่ดีที่จะอธิบายให้ได้มากที่สุดเท่าที่จะเป็นไปได้

คุณสามารถเลือก T เป็นคำนำหน้าเหมือนกับหลาย ๆ คนที่เลือกฉันสำหรับอินเทอร์เฟซ ดังนั้น

class Juice<TFruit> where TFruit...

จะเป็นชื่อที่ดีในความเห็นของฉัน ฉันชอบคำนำหน้าเป็นคำต่อท้ายในกรณีส่วนใหญ่เนื่องจากชัดเจนว่าคุณเห็นอะไรในเวลาที่คุณสะดุดเมื่อมันสะดุดและง่ายต่อการค้นหาด้วยสิ่งต่าง ๆ เช่น Intellisense เป็นแนวปฏิบัติที่ดีสำหรับ UI-Controls เช่นกันเมื่อคุณมักจะรู้ประเภท (เช่นกล่องข้อความ) แต่ไม่แน่ใจ 100% เกี่ยวกับชื่อที่คุณให้คำอธิบาย

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

class SomeAlgorithm<TypeT> where TypeT : Type

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


การใช้ส่วนTนำหน้าสำหรับพารามิเตอร์ประเภทและIสำหรับชื่ออินเตอร์เฟสจำเป็นต้องมีกฎ(" DO ... " อย่างชัดเจน ) ในแนวทางการออกแบบกรอบงาน
Richard

1
มันเป็นสิ่งที่น่าสงสัยโดยใช้ที่นี่นำมาสู่ตารางมากกว่าTFruit Tใช้ชื่อเช่นTTypeหรือTypeTเป็นเรื่องไร้สาระอย่างแน่นอน มันจะเพิ่มข้อมูลใด ๆTมากกว่าเพียงแค่ ข้อมูลเดียวกันที่แน่นอนถูกถ่ายทอด
Konrad Rudolph

@ Konrad Rudolph: ดูตัวอย่างของฉัน TypeT อย่างใกล้ชิดมันครอบคลุมกรณีพิเศษเมื่อจัดการกับ System.Type ฉันคิดว่าชื่อของฉันมีเอนโทรปีที่สูงกว่าการใช้ T สำหรับประเภทโดยเฉพาะถ้าชื่อสามัญนั้นถูก จำกัด ด้วยเช่นกัน
Falcon

7

Microsoft มีแนวทางอย่างเป็นทางการเกี่ยวกับข้อมูลทั่วไป: ชื่อของคลาส, โครงสร้างและอินเทอร์เฟซ (อ้างถึงที่นี่และในรูปแบบหนังสือ: แนวทางการออกแบบกรอบ )

เกี่ยวกับคำถามเฉพาะของคุณมันบอกว่า:

อย่าตั้งชื่อพารามิเตอร์ประเภททั่วไปที่มีชื่อที่สื่อความหมายเว้นแต่ชื่อตัวอักษรเดียวจะอธิบายตนเองได้อย่างสมบูรณ์และชื่อที่สื่อความหมายจะไม่เพิ่มมูลค่า

IDictionary<TKey, TValue> 

เป็นตัวอย่างของอินเทอร์เฟซที่เป็นไปตามหลักเกณฑ์นี้

พิจารณาใช้ตัวอักษร T เป็นชื่อพารามิเตอร์ประเภทสำหรับประเภทที่มีพารามิเตอร์ประเภทตัวอักษรเดียว

ทำชื่อพารามิเตอร์ประเภทคำอธิบายนำหน้าด้วยตัวอักษร T

พิจารณาระบุข้อ จำกัด ที่วางไว้บนพารามิเตอร์ type ในชื่อของพารามิเตอร์ ตัวอย่างเช่นพารามิเตอร์ที่ จำกัด กับ ISession อาจเรียกว่า TSession


การอ้างอิงที่ดีกว่าที่จะเป็นแนวทางการออกแบบกรอบหนังสือหรือ (สรุป) ใน MSDN สะดุดตารายชื่อเรียน Structs และการเชื่อมต่อ
Richard

@ Richard: ปรับคำตอบของฉันเมื่อพิจารณาถึงความคิดเห็นของคุณขอบคุณ!
Matthieu

2

จุดรวมของข้อมูลทั่วไปคือการมอบหมายการทำงาน - คลาสทั่วไปทำสิ่งหนึ่งอาร์กิวเมนต์ของมันทำสิ่งอื่น ตัวอย่างหนังสือเป็นคอลเล็กชันทั่วไป: คอลเล็กชันเก็บ 'สิ่ง' แต่ไม่สนใจว่าสิ่งเหล่านี้คืออะไร ชื่อสามัญ (sic!) ดังนั้นมีเหตุผลบางอย่างกับมัน - เราไม่ต้องการให้เป็นคำอธิบายเพราะไม่มีอะไรจะอธิบายนอกเหนือจาก "มันเป็นอาร์กิวเมนต์ประเภททั่วไป" ซึ่งชื่อTครอบคลุมอย่างหมดจด (พิจารณา อนุสัญญา) การอธิบายเป็นสิ่งที่ดี แต่การอธิบายที่มากเกินไปชี้ให้เห็นข้อ จำกัด ที่ไม่มีอยู่

อย่างไรก็ตามบางครั้งคลาสหรือวิธีการทั่วไปมีพารามิเตอร์ประเภทมากกว่าหนึ่งและ ณ จุดนี้มันทำให้รู้สึกเพื่อให้พวกเขามีชื่ออธิบายเพิ่มเติมเพื่อให้บทบาทของพวกเขากลายเป็นที่ชัดเจน ตัวอย่างที่ดีสำหรับประเภทการรวบรวมคีย์ - ค่าซึ่งทั้งคีย์และค่าเป็นแบบทั่วไป เรียกพวกเขาTและS(หรือQหรืออะไรก็ตาม) จะมีประโยชน์น้อยกว่าเรียกพวกเขาพูดKeyTypeและValueTypeหรือและTKeyTVal


1

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

ต่อไปนี้เป็นอนุสัญญาที่ฉันเรียนรู้และปฏิบัติตาม:

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

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

  • พารามิเตอร์ประเภททั่วไปหลายรายการในคลาสเดียวกันหรือการประกาศเมธอดควรเริ่มต้นด้วย T แต่จะแตกต่างกันด้วยวิธีการที่กระชับ แต่เข้าใจได้ง่าย TInและTOutตัวอย่างเช่นเป็น GTP ทั่วไปและเข้าใจกันดีสำหรับวิธีการที่ยอมรับอินพุตทั่วไปที่พิมพ์อย่างรุนแรงและสร้างเอาต์พุตทั่วไปที่พิมพ์ออกมาอย่างรุนแรง

  • หลายประเภทที่แตกต่าง แต่ไม่เหมือนกันเช่นสำหรับคลาสที่บรรจุเช่น. Tuple หรือประเภทผู้แทนเช่น Func, Predicate และ Action สามารถติดป้ายกำกับ T1, T2, T3 และอื่น ๆ อย่างไรก็ตามการประกาศ GTP ที่น่าทึ่ง (มีวัตถุประสงค์ที่ชัดเจนและ / หรือข้อ จำกัด ประเภทที่เฉพาะเจาะจงมาก) ควรมีคำอธิบายเพิ่มเติม

  • ประเภททั่วไปเดียวในวิธีการซึ่งแตกต่างจากประเภททั่วไปของชั้นเรียนที่มีสามารถอย่างใดอย่างหนึ่งสามารถปฏิบัติตามกฎก่อนหน้านี้เกี่ยวกับหลายประเภทในชั้นเรียนหรือวิธีการหรือถ้าเป็นประเภทที่ไม่ธรรมดาอื่น ๆ กว่าจะแตกต่างกัน ตัวอักษรเดียวบ่อยหรือU Vนี่คือการประชุมอีกครั้งย้อนหลังไปถึงเทมเพลต C ++

  • ไม่ว่าคุณจะเลือกทำอะไร อย่าติดป้าย GTP สำหรับชั้นหนึ่งและชั้นTถัดไปTParamเว้นแต่ชั้นที่สองจะซ้อนอยู่ในชั้นแรกทำให้Tไม่สามารถใช้งานได้ในชั้นที่สอง

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