Saya baru menyadari bahwa konstruk properti C # juga dapat digunakan dengan pengubah akses pribadi :
private string Password { get; set; }
Meskipun ini secara teknis menarik, saya tidak bisa membayangkan kapan saya akan menggunakannya karena bidang pribadi bahkan melibatkan lebih sedikit upacara :
private string _password;
dan saya tidak bisa membayangkan kapan saya harus bisa mendapatkan secara internal tetapi tidak mengatur atau mengatur tetapi tidak mendapatkan bidang pribadi:
private string Password { get; }
atau
private string Password { set; }
tapi mungkin ada kasus penggunaan dengan kelas bersarang / mewarisi atau mungkin di mana get / set mungkin berisi logika, bukan hanya memberikan kembali nilai properti, meskipun saya cenderung menjaga properti sangat sederhana dan membiarkan metode eksplisit melakukan logika apa pun, mis GetEncodedPassword()
.
Apakah ada yang menggunakan properti pribadi dalam C # untuk alasan apa pun atau hanya salah satu dari konstruksi kode yang secara teknis memungkinkan namun jarang digunakan?
Tambahan
Jawaban yang bagus, membacanya, saya menggunakan ini untuk properti pribadi:
- ketika bidang pribadi harus dimuat dengan malas
- ketika bidang pribadi membutuhkan logika tambahan atau nilai yang dihitung
- karena bidang pribadi bisa sulit untuk di-debug
- untuk "memberikan kontrak kepada diri sendiri"
- untuk secara internal mengkonversi / menyederhanakan properti yang terbuka sebagai bagian dari serialisasi
- membungkus variabel global untuk digunakan di dalam kelas Anda
sumber
Jawaban:
Saya menggunakannya jika saya perlu menyimpan nilai dan ingin memuatnya dengan malas.
sumber
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
sejak beberapa saat. Atau sebenarnya Resharper lebih suka :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
disebut selama konstruksi / inisialisasi objek yang mengandung dan bukan ketika properti pertama kali diakses.Penggunaan utama ini dalam kode saya adalah inisialisasi malas, seperti yang telah disebutkan orang lain.
Alasan lain untuk properti pribadi di atas bidang adalah bahwa properti pribadi jauh, jauh lebih mudah untuk di-debug daripada bidang pribadi. Saya sering ingin mengetahui hal-hal seperti "bidang ini diset secara tak terduga; siapa penelepon pertama yang menetapkan bidang ini?" dan itu jauh lebih mudah jika Anda bisa meletakkan breakpoint pada setter dan tekan go. Anda bisa memasukkan logging di sana. Anda dapat memasukkan metrik kinerja di sana. Anda bisa memasukkan cek konsistensi yang berjalan di build debug.
Pada dasarnya, ia datang ke: kode jauh lebih kuat daripada data . Setiap teknik yang memungkinkan saya menulis kode yang saya butuhkan adalah teknik yang bagus. Bidang jangan biarkan Anda menulis kode di dalamnya, properti lakukan.
sumber
Saya pribadi menggunakan ini bahkan ketika saya tidak membutuhkan logika pada pengambil atau penyetel properti. Menggunakan properti, bahkan properti pribadi, memang membantu membuktikan kode Anda di masa depan sehingga Anda dapat menambahkan logika ke pengambil nanti, jika diperlukan.
Jika saya merasa bahwa suatu properti pada akhirnya mungkin memerlukan logika tambahan, saya kadang-kadang akan membungkusnya menjadi properti pribadi alih-alih menggunakan bidang, jadi saya tidak perlu mengubah kode saya nanti.
Dalam kasus semi-terkait (meskipun berbeda dari pertanyaan Anda), saya sangat sering menggunakan setter pribadi di properti publik:
Ini memberi Anda pengambil publik, tetapi membuat setter tetap pribadi.
sumber
Satu penggunaan yang baik untuk properti hanya dapatkan pribadi adalah nilai yang dihitung. Beberapa kali saya memiliki properti yang hanya bisa dibaca pribadi dan hanya melakukan perhitungan pada bidang lain dalam tipe saya. Itu tidak layak metode dan tidak menarik untuk kelas lain jadi milik pribadi itu.
sumber
Inisialisasi malas adalah satu tempat di mana mereka bisa rapi, misalnya
Kemudian Anda dapat menulis: di
this.MyType
mana saja dan bukanthis.mytype.Value
merangkum fakta bahwa itu malas dipakai di satu tempat.Satu hal yang memalukan adalah bahwa C # tidak mendukung pelingkupan bidang dukungan ke properti (yaitu mendeklarasikannya di dalam definisi properti) untuk menyembunyikannya sepenuhnya dan memastikan bahwa itu hanya dapat diakses melalui properti.
sumber
field-declaration
dalamaccessor-declarations
memiliki peringkat nomor 1 pada daftar keinginan C # saya untuk waktu yang lama. Jika Anda bisa membuatnya dirancang dan diimplementasikan dalam beberapa versi (aktual) di masa depan, maka saya akan membuatkan kue untuk Anda.Satu-satunya penggunaan yang bisa saya pikirkan
sumber
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Properti dan bidang tidak satu banding satu. Properti adalah tentang antarmuka kelas (apakah berbicara tentang antarmuka publik atau internalnya), sedangkan bidang adalah tentang implementasi kelas. Properti tidak boleh dilihat sebagai cara untuk hanya mengekspos bidang, mereka harus dilihat sebagai cara untuk mengekspos maksud dan tujuan kelas.
Sama seperti Anda menggunakan properti untuk memberikan kontrak kepada konsumen Anda tentang apa yang merupakan kelas Anda, Anda juga dapat memberikan kontrak kepada diri sendiri untuk alasan yang sangat mirip. Jadi ya, saya menggunakan properti pribadi ketika itu masuk akal. Kadang-kadang properti pribadi dapat menyembunyikan detail implementasi seperti pemuatan malas, fakta bahwa properti benar-benar merupakan konglomerasi dari beberapa bidang dan aspek, atau bahwa properti harus secara virtual dipakai dengan setiap panggilan (pikirkan
DateTime.Now
). Pasti ada saat-saat di mana masuk akal untuk menegakkan ini bahkan pada diri Anda sendiri di backend kelas.sumber
Saya menggunakannya dalam serialisasi, dengan hal-hal seperti
DataContractSerializer
atau protobuf-net yang mendukung penggunaan ini (XmlSerializer
tidak). Ini berguna jika Anda perlu menyederhanakan objek sebagai bagian dari serialisasi:sumber
Satu hal yang saya lakukan sepanjang waktu adalah menyimpan variabel / cache "global"
HttpContext.Current
sumber
Saya menggunakannya setiap sekarang dan kemudian. Mereka dapat memudahkan untuk debug hal-hal ketika Anda dapat dengan mudah memasukkan breakpoint di properti atau Anda dapat menambahkan pernyataan logging dll.
Dapat juga berguna jika nanti Anda perlu mengubah jenis data dengan cara tertentu atau jika Anda perlu menggunakan refleksi.
sumber
Saya menggunakan properti pribadi untuk mengurangi kode untuk mengakses sub-properti yang sering digunakan.
Berguna jika ada banyak sub properti.
sumber
Ini adalah praktik umum untuk hanya memodifikasi anggota dengan metode get / set, bahkan yang pribadi. Sekarang, logika di balik ini adalah agar Anda tahu get / set Anda selalu berperilaku dengan cara tertentu (misalnya, menembakkan peristiwa) yang tampaknya tidak masuk akal karena itu tidak akan dimasukkan dalam skema properti ... tapi kebiasaan lama sulit.
sumber
Sangat masuk akal ketika ada logika yang terkait dengan set properti atau dapatkan (pikirkan inisialisasi malas) dan properti digunakan di beberapa tempat di kelas.
Jika itu hanya bidang pendukung lurus? Tidak ada yang terlintas dalam pikiran sebagai alasan yang baik.
sumber
Saya tahu pertanyaan ini sudah sangat lama tetapi informasi di bawah ini tidak ada dalam jawaban saat ini.
Jika Anda menyuntikkan dependensi Anda, Anda mungkin ingin memiliki Getter di Properti dan bukan setter karena ini akan menunjukkan Properti baca. Dengan kata lain Properti hanya dapat diatur dalam konstruktor dan tidak dapat diubah oleh kode lain di dalam kelas.
Visual Studio Professional juga akan memberikan informasi tentang Properti dan bukan bidang yang membuatnya lebih mudah untuk melihat bidang apa yang sedang digunakan.
sumber
Yah, karena tidak ada yang disebutkan Anda dapat menggunakannya untuk memvalidasi data atau untuk mengunci variabel.
Validasi
Mengunci
Catatan: Saat mengunci referensi Anda tidak mengunci akses ke anggota objek yang direferensikan.
Referensi malas: Ketika memuat malas Anda mungkin akhirnya perlu melakukannya async yang saat ini ada AsyncLazy . Jika Anda menggunakan versi yang lebih lama daripada Visual Studio SDK 2015 atau tidak menggunakannya, Anda juga dapat menggunakan AsyncEx's AsyncLazy .
sumber
Beberapa penggunaan yang lebih eksotis dari bidang eksplisit meliputi:
ref
atauout
dengan nilai - mungkin karena itu adalahInterlocked
penghitungstruct
dengan tata letak eksplisit (mungkin untuk memetakan ke dump C ++, atauunsafe
kode)BinaryFormatter
penanganan lapangan otomatis (mengubah ke props otomatis mengubah nama dan dengan demikian memecah serializer)sumber