ตัวดัดแปลงการเข้าถึงเริ่มต้นสำหรับคลาสวิธีการสมาชิกตัวสร้างผู้รับมอบสิทธิ์และอินเทอร์เฟซคืออะไร
ตัวดัดแปลงการเข้าถึงเริ่มต้นสำหรับคลาสวิธีการสมาชิกตัวสร้างผู้รับมอบสิทธิ์และอินเทอร์เฟซคืออะไร
คำตอบ:
การเข้าถึงเริ่มต้นสำหรับทุกอย่างใน C # คือ"การเข้าถึง จำกัด มากที่สุดที่คุณสามารถประกาศของสมาชิกว่า"
ตัวอย่างเช่น:
namespace MyCompany
{
class Outer
{
void Foo() {}
class Inner {}
}
}
เทียบเท่ากับ
namespace MyCompany
{
internal class Outer
{
private void Foo() {}
private class Inner {}
}
}
ข้อยกเว้นหนึ่งข้อในการทำเช่นนี้คือการทำให้ส่วนหนึ่งของพร็อพเพอร์ตี้ (โดยปกติคือ setter) ถูก จำกัด มากกว่าความสามารถในการเข้าถึงของคุณสมบัติที่ประกาศไว้:
public string Name
{
get { ... }
private set { ... } // This isn't the default, have to do it explicitly
}
นี่คือความหมายของข้อกำหนด C # 3.0 (ส่วน 3.5.1):
ขึ้นอยู่กับบริบทที่มีการประกาศสมาชิกเกิดขึ้นอนุญาตการเข้าถึงที่ประกาศบางประเภทเท่านั้น นอกจากนี้เมื่อการประกาศสมาชิกไม่รวมตัวดัดแปลงการเข้าถึงใด ๆ บริบทที่การประกาศเกิดขึ้นจะกำหนดความสามารถในการประกาศที่เป็นค่าเริ่มต้น
- namespaces โดยปริยายมีการประกาศการเข้าถึงสาธารณะ ไม่อนุญาตการปรับเปลี่ยนการเข้าถึงในการประกาศเนมสเปซ
- ประเภทที่ประกาศในหน่วยการรวบรวมหรือเนมสเปซสามารถมีความสามารถในการเข้าถึงสาธารณะหรือภายในที่ประกาศไว้
- สมาชิกของคลาสสามารถมีการเข้าถึงที่ประกาศไว้ห้าประเภทและเป็นค่าเริ่มต้นสำหรับการเข้าถึงแบบส่วนตัวที่ประกาศไว้ (โปรดทราบว่าประเภทที่ประกาศเป็นสมาชิกของคลาสสามารถมีความสามารถในการเข้าถึงที่ประกาศไว้ห้าชนิดในขณะที่ประเภทที่ประกาศเป็นสมาชิกของเนมสเปซสามารถเข้าถึงได้เฉพาะการประกาศสาธารณะหรือภายในเท่านั้น)
- สมาชิกโครงสร้างสามารถมีการเข้าถึงสาธารณะประกาศภายในหรือส่วนตัวประกาศและเริ่มต้นการเข้าถึงประกาศส่วนตัวเพราะ struct ถูกปิดผนึกโดยปริยาย สมาชิกโครงสร้างที่แนะนำในโครงสร้าง (นั่นคือไม่สืบทอดโดยโครงสร้างนั้น) ไม่สามารถป้องกันหรือป้องกันการเข้าถึงที่ประกาศภายใน (โปรดทราบว่าประเภทที่ประกาศเป็นสมาชิกของโครงสร้างสามารถมีการเข้าถึงสาธารณะประกาศภายในหรือส่วนตัวประกาศในขณะที่ประเภทประกาศเป็นสมาชิกของ namespace สามารถเข้าถึงได้เฉพาะสาธารณะหรือภายในประกาศ)
- สมาชิกอินเทอร์เฟซโดยนัยมีการประกาศการเข้าถึงสาธารณะ ไม่อนุญาตการปรับเปลี่ยนการเข้าถึงในการประกาศสมาชิกอินเตอร์เฟส
- การแจงนับสมาชิกโดยปริยายมีการประกาศการเข้าถึงสาธารณะ ไม่อนุญาตให้ผู้ดัดแปลงเข้าถึงการประกาศการแจงนับสมาชิก
(โปรดทราบว่าประเภทที่ซ้อนกันจะอยู่ภายใต้ส่วน "สมาชิกคลาส" หรือ "สมาชิกโครงสร้าง" - และดังนั้นจึงเป็นค่าเริ่มต้นการมองเห็นส่วนตัว)
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();
คุณไม่สามารถเข้าถึงได้M
ด้วยแต่คุณสามารถเข้าถึงได้ด้วยa.M()
(a as IFoo).M()
(ตรวจสอบข้อมูลจำเพาะสำหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลเฉพาะ)
คำตอบสั้น ๆ :เข้าถึงได้น้อยที่สุด (คำตอบของ Jon Skeet)
คำตอบยาว:
ประเภทที่ไม่ซ้อนกันการแจงนับและความสามารถในการเข้าถึงของผู้รับมอบสิทธิ์ (อาจมีความสามารถในการเข้าถึงภายในหรือสาธารณะเท่านั้น )
| Default | Permitted declared accessibilities ------------------------------------------------------------------ namespace | public | none (always implicitly public) enum | public | none (always implicitly public) interface | internal | public, internal class | internal | public, internal struct | internal | public, internal delegate | internal | public, internal
ประเภทซ้อนและการเข้าถึงของสมาชิก
| Default | Permitted declared accessibilities ------------------------------------------------------------------ namespace | public | none (always implicitly public) enum | public | none (always implicitly public) interface | public | none class | private | All¹ struct | private | public, internal, private² delegate | private | All¹ constructor | private | All¹ interface member | public | none (always implicitly public) method | private | All¹ field | private | All¹ user-defined operator| none | public (must be declared public)
¹ทั้งหมด === สาธารณะได้รับการป้องกันภายในส่วนตัวและได้รับการป้องกันภายใน
² structs ไม่สามารถสืบทอดจาก structs หรือคลาส (แม้ว่าจะสามารถ, อินเตอร์เฟส), ดังนั้นการป้องกันจึงไม่ใช่ตัวดัดแปลงที่ถูกต้อง
ความสามารถในการเข้าถึงประเภทซ้อนกันขึ้นอยู่กับโดเมนการช่วยสำหรับการเข้าถึงซึ่งกำหนดโดยความสามารถในการเข้าถึงที่ประกาศของสมาชิกและโดเมนการช่วยสำหรับการเข้าถึงของชนิดที่มีทันที อย่างไรก็ตามโดเมนความสามารถในการเข้าถึงของชนิดซ้อนกันจะต้องไม่เกินประเภทที่มีอยู่
หมายเหตุ: CIL ยังมีข้อกำหนดสำหรับการป้องกันและภายใน (ตรงข้ามกับการป้องกันที่มีอยู่ "หรือ" ภายใน ") แต่สำหรับความรู้ของฉันนี้ไม่สามารถใช้งานได้ใน C # ในปัจจุบัน
ดู:
http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- เรา / library / cx03xt0t.aspx
(ผู้ชายฉันรัก Microsoft URIs ... )
ดูที่Access Modifiers (คู่มือการเขียนโปรแกรม C #)
การเข้าถึงคลาสและโครงสร้าง
คลาสและโครงสร้างที่ประกาศโดยตรงภายในเนมสเปซ (กล่าวอีกนัยหนึ่งซึ่งไม่ซ้อนภายในคลาสหรือโครงสร้างอื่น) สามารถเป็นแบบสาธารณะหรือภายใน ภายในเป็นค่าเริ่มต้นหากไม่มีการระบุตัวแก้ไขการเข้าถึง
สมาชิกโครงสร้างรวมถึงคลาสที่ซ้อนกันและ structs สามารถประกาศเป็นสาธารณะภายในหรือส่วนตัว สมาชิกคลาสรวมถึงคลาสที่ซ้อนกันและ structs สามารถเป็นพับลิกได้รับการป้องกันภายใน, ได้รับการป้องกัน, ภายใน, มีการป้องกันแบบส่วนตัวหรือส่วนตัว ระดับการเข้าถึงสำหรับสมาชิกคลาสและสมาชิกโครงสร้างรวมถึงคลาสที่ซ้อนกันและโครงสร้างเป็นส่วนตัวโดยค่าเริ่มต้น ประเภทที่ซ้อนกันส่วนตัวไม่สามารถเข้าถึงได้จากนอกประเภทที่มี
คลาสที่ได้รับมาไม่สามารถเข้าถึงได้ง่ายกว่าประเภทฐาน กล่าวอีกนัยหนึ่งคุณไม่สามารถมีคลาสสาธารณะ B ที่เกิดขึ้นจากคลาสภายใน A หากได้รับอนุญาตมันจะมีผลในการทำให้ A เป็นสาธารณะเนื่องจากสมาชิกที่ได้รับการปกป้องหรือภายในทั้งหมดของ A สามารถเข้าถึงได้จากคลาสที่ได้รับ
คุณสามารถเปิดใช้ประกอบอื่น ๆ
InternalsVisibleToAttribute
ที่เฉพาะเจาะจงในการเข้าถึงประเภทภายในของคุณโดยใช้ สำหรับข้อมูลเพิ่มเติมดูชุดประกอบเพื่อนการเข้าถึงสมาชิกระดับและโครงสร้าง
สมาชิกคลาส (รวมถึงคลาสที่ซ้อนกันและโครงสร้าง) สามารถประกาศด้วยการเข้าถึงหกชนิดใด ๆ ไม่สามารถประกาศสมาชิกโครงสร้างได้รับการปกป้องเนื่องจากโครงสร้างไม่สนับสนุนการสืบทอด
โดยทั่วไปความสามารถในการเข้าถึงของสมาชิกจะไม่มากกว่าความสามารถในการเข้าถึงของประเภทที่มีอยู่ อย่างไรก็ตามสมาชิกสาธารณะของคลาสภายในอาจเข้าถึงได้จากนอกแอสเซมบลีถ้าสมาชิกใช้วิธีการอินเทอร์เฟซหรือแทนที่วิธีเสมือนที่กำหนดไว้ในคลาสพื้นฐานสาธารณะ
ประเภทของสมาชิกใด ๆ ที่เป็นเขตข้อมูลคุณสมบัติหรือเหตุการณ์ต้องมีอย่างน้อยที่สุดเท่าที่สมาชิกสามารถเข้าถึงได้ ในทำนองเดียวกันชนิดส่งคืนและชนิดพารามิเตอร์ของสมาชิกใด ๆ ที่เป็นวิธีการจัดทำดัชนีหรือผู้รับมอบสิทธิ์จะต้องสามารถเข้าถึงได้อย่างน้อยที่สุดเท่าที่สมาชิกสามารถเข้าถึงได้ ตัวอย่างเช่นคุณไม่สามารถมีเมธอดสาธารณะ M ที่ส่งคืนคลาส C ยกเว้นว่า C นั้นเป็นสาธารณะเช่นกัน ในทำนองเดียวกันคุณไม่สามารถมีคุณสมบัติที่ได้รับความคุ้มครองประเภท A ได้หากประกาศเป็นส่วนตัว
ตัวดำเนินการที่ผู้ใช้กำหนดต้องประกาศเป็นสาธารณะและคงที่เสมอ สำหรับข้อมูลเพิ่มเติมดูตัวดำเนินการมากไป
Finalizers ไม่สามารถปรับเปลี่ยนการเข้าถึงได้
ประเภทอื่น ๆ
อินเทอร์เฟซที่ประกาศโดยตรงภายในเนมสเปซสามารถประกาศเป็นสาธารณะหรือภายในและเช่นเดียวกับคลาสและโครงสร้างอินเทอร์เฟซเริ่มต้นสำหรับการเข้าถึงภายใน สมาชิกส่วนต่อประสานจะเปิดเผยต่อสาธารณะเสมอเนื่องจากจุดประสงค์ของอินเทอร์เฟซคือเพื่อให้ประเภทอื่น ๆ สามารถเข้าถึงคลาสหรือโครงสร้าง ไม่สามารถใช้ตัวดัดแปลงการเข้าถึงกับสมาชิกอินเตอร์เฟส
สมาชิกการแจงนับเป็นสาธารณะอยู่เสมอและไม่สามารถใช้ตัวดัดแปลงการเข้าถึงได้
ผู้รับมอบสิทธิ์ประพฤติเช่นคลาสและ structs โดยค่าเริ่มต้นพวกเขามีการเข้าถึงภายในเมื่อประกาศโดยตรงภายในเนมสเปซและการเข้าถึงส่วนตัวเมื่อซ้อนกัน
ชั้นภายในโดยค่าเริ่มต้น
อินเตอร์เฟซที่เป็นภายในโดยค่าเริ่มต้น
สมาชิกส่วนต่อประสานจะเป็นแบบสาธารณะโดยค่าเริ่มต้น (อินเทอร์เฟซจะไม่อนุญาตให้เราระบุการเข้าถึงใด ๆ กับสมาชิก)
หมายเหตุ:หากคุณพยายามระบุตัวระบุการเข้าถึงใด ๆ ให้กับสมาชิกของอินเตอร์เฟสมันจะแสดงข้อผิดพลาดในการคอมไพล์
โครงสร้างเป็นภายในโดยค่าเริ่มต้น
คำตอบที่ง่ายที่สุดคือต่อไปนี้ .....
สมาชิกทั้งหมดใน C # จะต้องใช้ตัวแก้ไขการเข้าถึงที่เป็นไปได้ของ LEAST โดยค่าเริ่มต้นเสมอ
นั่นคือเหตุผลที่คลาสระดับบนสุดทั้งหมดในแอสเซมบลีเป็นค่าเริ่มต้น "ภายใน" ซึ่งหมายความว่าพวกเขาเป็นสาธารณะในแอสเซมบลีที่พวกเขาอยู่ แต่ส่วนตัวหรือแยกออกจากการเข้าถึงการประกอบภายนอก ตัวเลือกอื่น ๆ สำหรับคลาสระดับบนสุดเป็นแบบสาธารณะซึ่งเข้าถึงได้ง่ายขึ้น สำหรับประเภทซ้อนกันมันเป็นส่วนตัวทั้งหมดยกเว้นข้อยกเว้นที่หายากบางอย่างเช่นสมาชิกของ enums และอินเทอร์เฟซที่สามารถเป็นสาธารณะได้เท่านั้น ตัวอย่างบางส่วน ในกรณีของคลาสและอินเตอร์เฟสระดับสูงสุดค่าดีฟอลต์คือ:
ชั้นสัตว์เช่นเดียวกับสัตว์ชั้นภายใน
อินเตอร์เฟซสัตว์เช่นเดียวกับสัตว์อินเตอร์เฟซสาธารณะ
ในกรณีของคลาสที่ซ้อนกันและอินเทอร์เฟซ (ชนิดภายใน) ค่าเริ่มต้นคือ:
ชั้นสัตว์เช่นเดียวกับสัตว์ชั้นส่วนตัว
สัตว์เช่นเดียวกับสัตว์อินเตอร์เฟซส่วนตัว
หากคุณเพียงแค่สมมติว่าค่าเริ่มต้นนั้นเป็นค่าส่วนตัวที่สุดเสมอคุณไม่จำเป็นต้องใช้อุปกรณ์เสริมจนกว่าคุณจะต้องเปลี่ยนค่าเริ่มต้น ง่าย.
Internal เป็นตัวปรับแต่งเริ่มต้น
ระดับเนมสเปซ: internal
ระดับประเภท: private