การมองเห็นคลาส Namespace เท่านั้นใน C # /. NET?


88

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


ฉันไม่เข้าใจคำถามของคุณ ฉันลบคำตอบของฉันออกเพราะคุณไม่ได้หมายถึง "ภายใน"?
Zyphrax

3
@nos: คุณกำลังมองหาความสามารถในการมองเห็นระดับแพ็คเกจของ Java ที่เทียบเท่าหรือไม่?
John Saunders

คำตอบ:



80

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

รับ C # Compiler เพื่อบังคับใช้ Namespace Visibility

มีบทความที่นี่ ( การมองเห็นเนมสเปซใน C # ) ที่แสดงวิธีการใช้คลาสบางส่วนเป็นรูปแบบของ "เนมสเปซปลอม" ซึ่งคุณอาจพบว่ามีประโยชน์

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

เป็นเคล็ดลับที่เรียบร้อย ... ตอนนี้อย่าทำ


1
เพิ่งพบตัวอย่าง:System.Net.Mime.MediaTypeNames.Application
Bitterblue

บทความกล่าวว่าคุณต้องนำหน้าทุกสายด้วยชื่อ "เนมสเปซ" ของคุณ แต่คุณไม่จำเป็นต้องใช้ C # 6 "ใช้แบบคงที่" คุณสามารถทำให้ "เนมสเปซ" เป็นคลาสบางส่วนแบบคงที่จากนั้นในโค้ดไคลเอนต์เขียน "โดยใช้แบบคงที่"
Pumkko

@Pumkko คลาสไม่จำเป็นต้องเป็นแบบคงที่เพื่อให้สามารถใช้คำสั่ง 'ใช้แบบคงที่' ได้แม้ว่าคุณจะใช้เป็นเนมสเปซก็ควรจะเป็นอยู่ดี
Fuzzy Logic

21

ภายในคือการประกอบ (โมดูลที่พูดอย่างเคร่งครัด) ไม่มีผลต่อการมองเห็นเนมสเปซ

วิธีเดียวที่จะบรรลุความเป็นส่วนตัวของชั้นเรียนจากชั้นเรียนอื่น ๆ ในชุดเดียวกันคือชั้นเรียนเป็นชั้นใน

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

หากได้รับการป้องกันทุกคนจะมองเห็นได้เมื่อเป็นส่วนตัว แต่ยังมองเห็นได้สำหรับคลาสย่อยของคลาสภายนอก

public class Outer
{
    private class Hidden     { public Hidden() {} }
    protected class Shady    { public Shady() {} }
    public class Promiscuous { public Promiscuous() {} }
}

public class Sub : Outer
{
    public Sub():base() 
    {
        var h = new Hidden();      // illegal, will not compile
        var s = new Shady();       // legal
        var p = new Promiscuous(); // legal
    }
}

public class Outsider 
{
    public Outsider() 
    {
        var h = new Outer.Hidden();      // illegal, will not compile
        var s = new Outer.Shady()        // illegal, will not compile
        var p = new Outer.Promiscuous(); // legal
    }
}

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


@ShuggyCoUK: public class Sub: Outer ควรปิดผนึก public class Sub: Outer ??? +1 แม้ว่า ... มันเหมาะกับฉัน
IAbstract

0

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


0

ไม่แน่ใจว่าเป็นไปได้โดยตรงหรือไม่ แต่วิธีที่ดีในการปลอมแปลงจะเป็น:

1) มีคลาสที่ต้องการสิ่งเหล่านี้สืบทอดมาจากคลาสเดียวซึ่งมีคลาสตัวช่วยเป็นคลาสภายใน

2) ใช้วิธีการขยายจากนั้นอ้างอิงเฉพาะวิธีการขยายภายในเนมสเปซ

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