อะไรคือความหมายของตัวปรับการเข้าถึง C # ที่วางแผนไว้


133

ในฐานะที่เป็นส่วนหนึ่งของเอกสารRoslynบน GitHub มีหน้าที่เรียกว่าสถานะการใช้งานคุณลักษณะภาษาพร้อมด้วยคุณลักษณะภาษาที่วางแผนไว้สำหรับ C # และ VB

คุณลักษณะหนึ่งที่ฉันไม่สามารถคาดเดาได้คือprivate protectedตัวปรับการเข้าถึง:

private protected string GetId() { … } 

นอกจากนี้ยังมีหน้าหมายเหตุการออกแบบภาษา C #ซึ่งอธิบายถึงคุณลักษณะใหม่ ๆ มากมาย แต่ไม่ใช่คุณลักษณะนี้

Eric Lippert กล่าวในความคิดเห็น :

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

ความหมายของprivate protectedอะไร? ฉันจะใช้เมื่อใด


2
โปรดทราบว่ามีข้อมูลเกี่ยวกับเรื่องนี้ภายใต้บันทึกการออกแบบภาษา VB
Jesse Good

3
เป็นการแมปไปยัง MethodAttributes.FamANDAssem C # มีการแมปภายในที่แปลกมันใช้ (ส่วนตัว | FamANDAssem) และแผนที่ที่มีการป้องกันภายในไปยัง (ส่วนตัว | ครอบครัว) แอตทริบิวต์ CLR นั้นแปลก
Hans Passant

22
คุณลักษณะที่เสนอนี้จะทำให้ความคิดเห็นของฉันไม่ถูกต้อง
Eric Lippert

ทีมออกแบบ C # ได้เผยแพร่แบบสำรวจพร้อมด้วยไวยากรณ์ทางเลือกที่แนะนำสำหรับคุณลักษณะนี้ บางส่วนของเหล่านี้เป็นที่น่าสนใจเช่นprotected & internal, assembly protectedหรือproternal(ฉันหวังว่าจะมีบางส่วนของเรื่องตลกเหล่านี้) นอกจากนี้ยังมีหัวข้อสนทนาที่มีข้อมูลเชิงลึกที่ดี
Kobi

1
ขณะนี้คุณลักษณะนี้ถูกทำเครื่องหมายในสถานะการใช้งานคุณลักษณะภาษา! โดยส่วนตัวแล้วฉันชอบแนวคิดของระดับการเข้าถึงนี้และฉันคิดว่ามันเป็นคุณสมบัติที่มีประโยชน์ ฉันต้องการใช้การป้องกันเพื่อให้รหัสของฉันเป็นไปตามการออกแบบชั้นเรียน แต่ฉันไม่ต้องการให้คนอื่นเขียนคลาสย่อยที่แฮ็กเพื่อเข้าถึงสมาชิกคนนี้ IMO ทางออกที่ดีที่สุดคือถ้าเราเขียนได้protected | internalและprotected & internal
Felix Keil

คำตอบ:


98

อ้างอิงจาก " Professional C # 2008 " โดย De Bill Evjen และ Jay Glynn, หน้า 1699:

ส่วนตัวได้รับการป้องกัน - "เฉพาะประเภทที่ได้รับภายในแอสเซมบลีปัจจุบัน"

C ++ / CLI มีคุณสมบัติคล้ายกัน - กำหนดและใช้คลาสและโครงสร้าง (C ++ / CLI)> การมองเห็นของสมาชิก :

private protected-or- protected private- สมาชิกได้รับการคุ้มครองภายในที่ชุมนุม แต่เป็นส่วนตัวภายนอกที่ชุมนุม


72
ดังนั้นจึง "ป้องกันและภายใน" แทนที่จะเป็น "ป้องกันหรือภายใน"?
user541686

2
ตอนนี้จะเป็นไปได้ไหมที่จะให้สมาชิกที่สามารถเข้าถึงคลาสที่ได้รับมายอมรับหรือส่งคืนสิ่งของinternalประเภทต่างๆโดยไม่ต้องให้สมาชิกเปิดเผยตัวเองกับทุกสิ่งในการชุมนุม
supercat

ขอบคุณ! ฉันไม่ได้คิดถึงเรื่องนั้น internalที่จริงผมมีกรณีที่ผมจะได้นำมาใช้ที่ปรับปรุงและกลับลงไปใน
Kobi

3
การดำรงอยู่ของข้อเสนอนี้ / คุณลักษณะที่ดูเหมือนว่าจะชี้ให้เห็นว่าinternalการมองเห็น (ที่เกี่ยวข้องกับการที่ชั้นจะกำหนด) มันตั้งฉากกับpublic/ protected/ privateการแสดงผล (ที่เกี่ยวข้องกับมรดก) และบางทีinternalควรจะปรับปรุงของตัวเองแยกออกจากpublic/ /protected private
jpmc26

1
@jww - ฉันไม่ค่อยคุ้นเคยกับ Java แต่เท่าที่ฉันรู้packageใน Java นั้นเหมือนเนมสเปซใน C # มากกว่า
Gogutz

187

นี่คือตัวแก้ไขการเข้าถึงทั้งหมดในแผนภาพเวนน์ตั้งแต่การ จำกัด มากขึ้นไปจนถึงการสำส่อนมากขึ้น:

private:
ป้อนคำอธิบายภาพที่นี่

private protected: - เพิ่มใน C # 7.2
ป้อนคำอธิบายภาพที่นี่

internal:
ป้อนคำอธิบายภาพที่นี่

protected:
ป้อนคำอธิบายภาพที่นี่

protected internal:
ป้อนคำอธิบายภาพที่นี่

public:
ป้อนคำอธิบายภาพที่นี่


3
ภาพที่มา: การเข้าถึง Modifiers.pdn ผมใช้ชื่อ aptly Paint.Net
Kobi

9
แผนภาพเหล่านี้อยู่ที่ไหนในชีวิต (C #) ทั้งหมดของฉัน? พวกเขายอดเยี่ยมมาก - ขอบคุณ!
Jon Peterson

28

นี่เป็นเพียงเพื่อให้กราฟ (สร้างด้วยhttp://ashitani.jp/gv/ ) ของระดับการเข้าถึงที่แตกต่างกัน (รูปภาพไม่ตรงกับความคิดเห็น)

แผนภาพ Digraph ของระดับการเข้าถึง C #

ลูกศรแต่ละลูกหมายถึง "มีข้อ จำกัด มากกว่า"

ชื่อ CLR มีPrivate, FamilyANDAssembly, Assembly, Family, ,FamilyORAssemblyPublic


แก้ไขในภายหลัง: ปรากฎว่าระดับการเข้าถึงใหม่ที่ดีนี้ (ด้วยชื่อที่ไม่ดีจริงๆ) ไม่รวมอยู่ใน C # 6.0 ในที่สุด ได้รับการสนับสนุนจาก C # 7.2 เท่านั้น (และฉันเห็นว่าคุณอัปเดตคำถาม "แท็ก" ของคุณ)


มันอาจจะเป็นฉัน แต่ดูเหมือนว่าลูกศรจะไปในทิศทางที่ 'จำกัด น้อยกว่า'
acarlon

4
@acarlon ใช่ดังนั้นa → bในแผนภาพจึงหมายความว่า " aมีข้อ จำกัด มากกว่าb" ดังนั้นคุณสามารถ "อ่าน" ลูกศรว่า "มีข้อ จำกัด มากกว่า" (นั่นคือสิ่งที่ฉันพยายามอธิบาย) ดังนั้นลูกศรจึงชี้ในข้อ จำกัด น้อยที่สุด " ทิศทาง". รูปแบบที่ตรงกันข้ามสำหรับลูกศรอาจดีพอ ๆ กัน แต่ฉันต้องเลือกการประชุมเดียว
Jeppe Stig Nielsen

10

เป็นเพียงการคาดเดา แต่จากชื่อคุณอาจเดาได้ว่าเป็นเวอร์ชันที่ จำกัด มากขึ้นprotected(หรือเวอร์ชันที่ผ่อนคลายมากขึ้นprivateหากคุณต้องการ) และตัวแปรที่สมเหตุสมผลเท่านั้นคือการ จำกัดprotectedพฤติกรรมในการชุมนุม

การใช้งานที่เป็นไปได้: จากนั้นคุณต้องการมีprotectedไว้สำหรับการใช้งานภายใน แต่ไม่ใช่สำหรับการใช้งานภายนอก (และคุณไม่ต้องการปิดผนึกคลาส)

PS มันมีอยู่เสมอในCLR แต่ไม่ได้อยู่ใน C # มันเป็นการรวมกันของprotected และ internalอ้าง:

CLR ยังรองรับการเข้าถึงประเภท "Family and assembly" ซึ่งหมายความว่าวิธีนี้สามารถเข้าถึงได้จากภายในประเภทการประกาศประเภทที่ซ้อนกันและประเภทที่ได้รับ แต่จะมีการประกาศในแอสเซมบลีเดียวกันเท่านั้น เห็นได้ชัดว่าทีม C # ไม่ได้คิดว่านี่เป็นคุณสมบัติที่มีประโยชน์มากดังนั้นจึงไม่รองรับในภาษานี้


+1 สำหรับความคิดเห็น CLR - ฉันใช้เวลามากใน C # และในภาษา. NET อื่น ๆ น้อยมากจนบางครั้งฉันลืมไปว่ามันไม่ใช่สิ่งเดียวกัน
brichins

@DarrelHoffman ขอบคุณที่สังเกต! ฉันผสมความคิดของฉันที่นี่เล็กน้อย)
Petr Abdulin

5

"อาจจะ" มองเห็นได้เฉพาะคลาสย่อยที่อยู่ในแอสเซมบลีเดียวกัน นี้จะทำให้มันเล็ก ๆ น้อย ๆ ที่ถูก จำกัด protectedกว่า


1

ดูข้อมูลจำเพาะสำหรับคุณลักษณะ "ป้องกันส่วนบุคคล":

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

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