Visibilitas kelas khusus namespace di C # /. NET?

88

Di C #, dapatkah Anda membuat kelas hanya terlihat di dalam namespace-nya sendiri tanpa tinggal di rakitan yang berbeda? Tampaknya ini berguna untuk kelas helper biasa yang tidak boleh digunakan di tempat lain. (yaitu, apa yang disebut Java kelas privat paket)

no
sumber
Saya tidak mengerti pertanyaan Anda. Saya menghapus jawaban saya karena Anda tidak bermaksud "internal"?
Zyphrax
3
@nos: apakah Anda mencari yang setara dengan visibilitas tingkat paket java?
John Saunders

Jawaban:

35

Saya tidak berpikir bahwa apa yang Anda inginkan itu mungkin.

Steven Sudit
sumber
80

Anda dapat membuat kelas internaltetapi ini hanya mencegah siapa pun di luar rakitan menggunakan kelas tersebut. Tetapi Anda masih harus membuat assembly terpisah untuk setiap namespace yang Anda inginkan. Saya berasumsi itulah mengapa Anda tidak ingin melakukannya.

Mendapatkan Compiler C # untuk Menerapkan Visibilitas Namespace

Ada artikel di sini ( Visibilitas ruang nama di C # ) yang menunjukkan metode penggunaan kelas parsial sebagai bentuk "ruang nama palsu" yang mungkin berguna bagi Anda.

Penulis menunjukkan bahwa ini tidak bekerja dengan sempurna dan dia membahas kekurangannya. Masalah utamanya adalah bahwa desainer C # mendesain C # agar tidak bekerja seperti ini. Ini sangat menyimpang dari praktik pengkodean yang diharapkan di C # / .NET, yang merupakan salah satu keuntungan terbesar .NET Frameworks.

Ini trik yang bagus… sekarang jangan lakukan itu.

Robert Cartaino
sumber
1
Baru saja menemukan contoh:System.Net.Mime.MediaTypeNames.Application
Bitterblue
Artikel tersebut mengatakan bahwa Anda harus mengawali setiap panggilan dengan nama "namespace" Anda, tetapi Anda tidak membutuhkannya dengan C # 6 "menggunakan statis". Anda dapat membuat "namespace" menjadi kelas parsial statis dan kemudian di kode klien tulis "menggunakan statis"
Pumkko
@Pumkko Kelas tidak perlu statis untuk dapat menggunakan pernyataan 'menggunakan statis', meskipun jika Anda menggunakannya sebagai namespace maka itu harus tetap.
Fuzzy Logic
21

internal adalah privasi perakitan (tepatnya modul). Ini tidak berpengaruh pada visibilitas namespace.

Satu-satunya cara untuk mencapai privasi kelas dari kelas lain dalam rakitan yang sama adalah untuk kelas menjadi kelas dalam.

Pada titik ini, jika kelas itu privat, ia tidak terlihat oleh apa pun yang tidak ada di kelas itu atau kelas luar itu sendiri.

Jika diproteksi, ini terlihat oleh semua orang yang bisa melihatnya saat privat tetapi juga terlihat oleh sub kelas dari kelas luar.

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
    }
}

Intinya satu-satunya cara untuk mencapai apa yang Anda inginkan adalah dengan menggunakan kelas luar sebagai bentuk namespace dan membatasi di dalam kelas itu.

ShuggyCoUk
sumber
@ShuggyCoUK: kelas umum Sub: Luar harus disegel kelas umum Sub: Luar ??? +1 meskipun ... itu bekerja untuk saya
IAbstract
0

Jika Anda memiliki satu rakitan, Anda dapat menentukan ruang nama dalam rakitan itu sebanyak yang Anda inginkan, tetapi apa pun pengubah yang Anda terapkan di IDE, Anda akan selalu dapat melihat kelas di ruang nama lain.

Nathan
sumber
0

Tidak yakin apakah itu mungkin secara langsung, tetapi beberapa cara yang baik untuk memalsukannya adalah:

1) Minta kelas yang membutuhkan barang semacam ini mewarisi dari satu kelas yang memiliki kelas pembantu sebagai kelas internal.

2) Gunakan metode ekstensi dan kemudian hanya mereferensikan metode ekstensi dalam namespace.

Wyatt Barnett
sumber