Apa arti dari pengubah akses C # “private protected” yang direncanakan?

133

Sebagai bagian dari dokumentasi Roslyn tentang GitHub, ada halaman yang disebut status implementasi fitur Bahasa , dengan fitur bahasa yang direncanakan untuk C # dan VB.

Salah satu fitur yang saya tidak dapat membungkus kepala saya adalah private protectedpengubah akses:

private protected string GetId() {  } 

Ada juga halaman Catatan Desain Bahasa C # , yang menjelaskan banyak fitur baru, tetapi tidak yang ini.

Eric Lippert berkata dalam komentar :

Kesalahan Anda adalah menganggap pengubah sebagai peningkatan pembatasan. Pengubah sebenarnya selalu mengurangi batasan. Ingat, semuanya "pribadi" secara default; hanya dengan menambahkan pengubah Anda membuatnya kurang dibatasi.

Apa artinya private protected? Kapan saya bisa menggunakannya?

Kobi
sumber
2
Perhatikan bahwa ada informasi tentang itu di bawah catatan desain bahasa VB .
Jesse Good
3
Ini adalah pemetaan untuk MethodAttributes.FamANDAssem. C # memiliki pemetaan internal yang aneh , menggunakan (Private | FamANDAssem). Dan peta yang dilindungi internal ke (Pribadi | Keluarga). Atribut CLR aneh.
Hans Passant
22
Fitur yang diusulkan ini akan membuat komentar saya salah.
Eric Lippert
Tim desain C # telah menerbitkan survei dengan sintaks alternatif yang disarankan untuk fitur ini. Beberapa di antaranya menarik, seperti protected & internal, assembly protectedatau proternal(saya harap beberapa di antaranya adalah lelucon). Ada juga utas Diskusi dengan beberapa wawasan yang bagus.
Kobi
1
Fitur sekarang ditandai ditarik dalam status implementasi Fitur Bahasa! Secara pribadi saya suka ide tingkat akses ini dan saya pikir ini fitur yang berguna. Saya ingin menggunakan yang dilindungi untuk menjaga kode saya sesuai dengan desain kelas, tapi saya tidak ingin orang lain menulis sublasses yang bisa diakses oleh anggota ini. IMO solusi terbaik adalah jika kita bisa menulis protected | internaldanprotected & internal
Felix Keil

Jawaban:

98

Menurut " Professional C # 2008 " oleh De Bill Evjen dan Jay Glynn, halaman 1699:

dilindungi pribadi - "hanya tipe turunan dalam perakitan saat ini"

C ++ / CLI memiliki fitur serupa - Tentukan dan Konsumsi Kelas dan Struktur (C ++ / CLI)> Visibilitas Anggota :

private protected-atau- protected private- Anggota dilindungi di dalam majelis tetapi pribadi di luar majelis.

Gogutz
sumber
72
Jadi itu "dilindungi dan internal" bukan "dilindungi atau internal"?
user541686
2
Apakah sekarang mungkin untuk memiliki anggota yang dapat diakses oleh kelas turunan menerima atau mengembalikan barang-barang internalsejenis tanpa mengharuskan anggota itu sendiri terkena segala sesuatu di majelis?
supercat
Terima kasih! Saya tidak memikirkan hal itu. Saya benar-benar memiliki case saya akan menggunakan pengubah itu, dan jatuh kembali internal.
Kobi
3
Keberadaan proposal / fitur ini tampaknya menunjukkan bahwa internalvisibilitas (terkait dengan di mana kelas didefinisikan) benar-benar ortogonal ke public/ protected/ privatevisibilitas (terkait dengan warisan) dan bahwa, mungkin, internalharus pengubah sendiri terpisah dari public/ protected/ private.
jpmc26
1
@jww - Saya tidak terlalu terbiasa dengan Java, tetapi sebanyak yang saya tahu packagedi Jawa lebih mirip namespace di C #.
Gogutz
187

Berikut ini semua pengubah akses dalam diagram Venn, dari yang lebih membatasi hingga yang lebih bebas:

private:
masukkan deskripsi gambar di sini

private protected: - ditambahkan dalam C # 7.2
masukkan deskripsi gambar di sini

internal:
masukkan deskripsi gambar di sini

protected:
masukkan deskripsi gambar di sini

protected internal:
masukkan deskripsi gambar di sini

public:
masukkan deskripsi gambar di sini

Kobi
sumber
3
Gambar sumber: Access Modifiers.pdn . Saya menggunakan Paint.Net .
Kobi
9
Di manakah diagram-diagram ini selama hidupku (C #)? Mereka luar biasa - terima kasih!
Jon Peterson
28

Ini hanya untuk memberikan grafik (dibuat dengan http://ashitani.jp/gv/ ) dari tingkat aksesibilitas yang berbeda (gambar tidak sesuai dengan komentar).

diagram diagram tingkat akses C #

Setiap panah berarti "lebih membatasi daripada".

Nama-nama CLR adalah Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Sunting kemudian: Ternyata tingkat akses baru yang bagus ini (dengan nama yang sangat buruk) pada akhirnya tidak termasuk dalam C # 6.0. Ini didukung hanya dari C # 7.2 (dan saya melihat Anda memperbarui "tag" pertanyaan Anda).

Jeppe Stig Nielsen
sumber
Mungkin hanya aku, tapi panah tampaknya menuju ke arah 'kurang ketat daripada'.
acarlon
4
@acarlon Ya, jadi a → bdalam diagram berarti " alebih membatasi daripada b", jadi Anda dapat "membaca" panah sebagai "lebih membatasi daripada" (itulah yang saya coba jelaskan), jadi panah menunjuk pada yang paling tidak membatasi " arah". Kebalikan dari konvensi untuk panah bisa saja sama baiknya, tetapi saya harus memilih satu konvensi.
Jeppe Stig Nielsen
10

Ini hanya tebakan, tetapi dari nama Anda mungkin bisa menebak itu versi yang lebih terbatas protected, (atau versi yang lebih santai privatejika Anda mau). Dan hanya varian yang masuk akal yang membatasiprotected perilaku perakitan.

Kemungkinan penggunaan: maka Anda ingin memilikinya protected untuk implementasi internal, tetapi tidak untuk penggunaan eksternal (dan Anda tidak ingin menyegel kelas).

PS Itu selalu ada di CLR, tetapi tidak di C # . Ini kombinasi dari protected dan internal , kutipan:

CLR juga mendukung tipe akses “Family and assembly”. Ini berarti bahwa metode ini dapat diakses dari dalam tipe deklarasi, tipe bersarang dan diturunkan tetapi hanya jika mereka dinyatakan dalam majelis yang sama. Yah, tampaknya tim C # tidak menganggap ini sebagai fitur yang sangat berguna sehingga tidak didukung dalam bahasa ini.

Petr Abdulin
sumber
+1 untuk komentar CLR - Saya menghabiskan begitu banyak waktu di C # dan begitu sedikit dalam bahasa .NET lainnya hari ini yang kadang-kadang saya lupa mereka bukan hal yang sama.
brichins
@DarrelHoffman terima kasih atas perhatiannya! Saya sedikit mengacaukan pikiran saya di sini)
Petr Abdulin
5

"Mungkin" hanya dapat dilihat oleh subkelas yang berada dalam rakitan yang sama. Ini membuatnya sedikit dibatasi daripada protected.

Mehmet Ataş
sumber
1

Lihat spesifikasi untuk fitur "dilindungi pribadi":

Arti intuitif dari private protected adalah "dapat diakses dalam majelis ini dengan tipe yang berasal dari kelas yang mengandung".

Julien Couvreur
sumber