Saya menyadari bahwa itu sepertinya duplikat Apa perbedaan antara Field dan Properti di C #? tetapi pertanyaan saya memiliki sedikit perbedaan (dari sudut pandang saya):
Begitu saya tahu itu
- Saya tidak akan menggunakan kelas saya dengan "teknik yang hanya bekerja pada properti" dan
- Saya tidak akan menggunakan kode validasi dalam pengambil / penyetel.
Apakah ada perbedaan (kecuali gaya / pengembangan masa depan), seperti beberapa jenis kontrol dalam pengaturan properti?
Apakah ada perbedaan tambahan antara:
public string MyString { get; set; }
dan
public string myString;
(Saya sadar bahwa, versi pertama memerlukan C # 3.0 atau lebih tinggi dan bahwa kompiler memang membuat bidang pribadi.)
Jawaban:
Enkapsulasi.
Dalam contoh kedua Anda baru saja mendefinisikan sebuah variabel, pada contoh pertama, ada pengambil / penyetel di sekitar variabel. Jadi jika Anda memutuskan untuk memvalidasi variabel di kemudian hari - itu akan jauh lebih mudah.
Plus mereka tampil berbeda di Intellisense :)
Sunting: Perbarui untuk pertanyaan yang diperbarui OP - jika Anda ingin mengabaikan saran lain di sini, alasan lainnya adalah karena itu sama sekali bukan desain OO yang bagus. Dan jika Anda tidak memiliki alasan yang sangat baik untuk melakukannya, selalu pilih properti daripada variabel / bidang publik.
sumber
Bidang dan properti terlihat sama, tetapi tidak. Properti adalah metode dan karena itu ada hal-hal tertentu yang tidak didukung untuk properti, dan beberapa hal yang mungkin terjadi dengan properti tetapi tidak pernah dalam kasus bidang.
Berikut daftar perbedaannya:
out/ref
argumen. Properti tidak bisa.DateTime.Now
itu tidak selalu sama dengan dirinya sendiri.readonly
)MemberTypes
sehingga lokasinya berbeda (GetFields
vsGetProperties
misalnya)sumber
Pasangan cepat, perbedaan yang jelas
Properti dapat memiliki accessor atau kata kunci.
Properti dapat diganti dalam keturunan.
sumber
Perbedaan mendasar adalah bahwa bidang adalah posisi di memori tempat data dari jenis yang ditentukan disimpan. Properti mewakili satu atau dua unit kode yang dieksekusi untuk mengambil atau menetapkan nilai dari jenis yang ditentukan. Penggunaan metode pengakses ini disembunyikan secara sintaksis dengan menggunakan anggota yang tampaknya berperilaku seperti bidang (dalam hal itu dapat muncul di kedua sisi operasi penugasan).
sumber
Pengakses lebih dari bidang. Yang lain sudah menunjukkan beberapa perbedaan penting, dan saya akan menambahkan satu lagi.
Properti ambil bagian dalam kelas antarmuka. Sebagai contoh:
Antarmuka ini dapat dipenuhi dengan beberapa cara. Sebagai contoh:
Dalam implementasi ini kami melindungi kedua
Person
kelas agar tidak masuk ke keadaan tidak valid, serta penelepon agar tidak keluar dari properti yang belum ditetapkan.Tapi kami bisa mendorong desain lebih jauh. Misalnya, antarmuka mungkin tidak berurusan dengan setter. Sangat sah untuk mengatakan bahwa konsumen
IPerson
antarmuka hanya tertarik untuk mendapatkan properti, bukan dalam pengaturannya:Implementasi
Person
kelas sebelumnya memenuhi antarmuka ini. Fakta bahwa itu memungkinkan penelepon juga mengatur properti tidak ada artinya dari sudut pandang konsumen (yang mengkonsumsiIPerson
). Fungsionalitas tambahan dari implementasi konkret dipertimbangkan oleh, misalnya, pembangun:Dalam kode ini, konsumen tidak tahu tentang setter properti - bukan urusannya untuk mengetahuinya. Konsumen hanya membutuhkan getter, dan ia mendapatkan getter dari antarmuka, yaitu dari kontrak.
Implementasi lain yang benar-benar valid
IPerson
adalah kelas orang yang tidak dapat diubah dan pabrik orang yang sesuai:Dalam contoh kode ini, konsumen sekali lagi tidak memiliki pengetahuan untuk mengisi properti. Konsumen hanya berurusan dengan getter dan implementasi konkret (dan logika bisnis di belakangnya, seperti pengujian jika nama kosong) diserahkan kepada kelas khusus - pembangun dan pabrik. Semua operasi ini sama sekali tidak mungkin dengan bidang.
sumber
Yang pertama:
adalah properti; yang kedua (
public string MyString
) menunjukkan suatu bidang.Perbedaannya adalah, bahwa teknik-teknik tertentu (penyatuan data ASP.NET untuk instance), hanya bekerja pada properti, dan bukan pada bidang. Hal yang sama berlaku untuk Serialisasi XML: hanya properti yang diserialisasi, bidang tidak diserialisasi.
sumber
Properti dan Fields mungkin, dalam banyak kasus, tampak serupa, tetapi mereka tidak. Ada batasan untuk properti yang tidak ada untuk bidang, dan sebaliknya.
Seperti yang telah disebutkan orang lain. Anda dapat membuat properti hanya-baca atau hanya-menulis dengan menjadikannya aksesor atau pribadi. Anda tidak dapat melakukannya dengan bidang. Properti juga bisa virtual, sementara bidang tidak bisa.
Pikirkan properti sebagai gula sintaksis untuk fungsi getXXX () / setXXX (). Ini adalah bagaimana mereka diimplementasikan di belakang layar.
sumber
Ada satu perbedaan penting lainnya antara bidang dan properti.
Saat menggunakan WPF, Anda hanya dapat mengikat ke properti publik. Mengikat ke bidang publik tidak akan berfungsi. Ini benar bahkan ketika tidak menerapkan
INotifyPropertyChanged
(meskipun Anda harus selalu melakukannya).sumber
Di antara jawaban dan contoh lain, saya pikir contoh ini berguna dalam beberapa situasi.
Misalnya, katakan Anda memiliki yang berikut:
OnChange
property
Jika Anda ingin menggunakan delegasi, Anda perlu mengubahnya
OnChange
menjadifield
seperti ini:Dalam situasi seperti itu kami melindungi bidang kami dari akses atau modifikasi yang tidak diinginkan.
sumber
Anda harus selalu menggunakan properti alih-alih bidang untuk bidang publik apa pun. Ini memastikan bahwa perpustakaan Anda memiliki kemampuan untuk menerapkan enkapsulasi untuk bidang apa pun jika diperlukan di masa depan tanpa melanggar kode yang ada. Jika Anda mengganti bidang dengan properti di perpustakaan yang ada maka semua modul dependen menggunakan perpustakaan Anda juga perlu dibangun kembali.
sumber