Saya mengambil kelas C # sekarang dan saya mencoba mencari cara terbaik untuk melakukan sesuatu. Saya berasal dari latar belakang Java sehingga saya hanya terbiasa dengan praktik terbaik Java; Saya pemula C #!
Di Jawa, jika saya memiliki properti pribadi, saya melakukan ini;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
Di C #, saya melihat ada banyak cara untuk melakukan ini.
Saya bisa melakukannya seperti Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
Atau saya bisa melakukannya dengan cara ini:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
Atau:
public string Name { get; set; }
Manakah yang harus saya gunakan, dan peringatan atau kehalusan apa yang terlibat dengan setiap pendekatan? Saat membuat kelas, saya mengikuti praktik terbaik umum yang saya ketahui dari Java (terutama membaca Java Efektif). Jadi misalnya, saya menyukai kekekalan (menyediakan penyetel hanya jika diperlukan). Saya hanya ingin tahu bagaimana praktik ini cocok dengan berbagai cara menyediakan setter dan getter di C #; pada dasarnya, bagaimana saya menerjemahkan praktik terbaik dari dunia Java ke dalam C #?
EDIT
Saya memposting ini sebagai komentar untuk jawaban Jon Skeet tetapi kemudian menjadi panjang:
Bagaimana dengan properti non-sepele (yaitu, dengan pemrosesan dan validasi yang signifikan mungkin)? Bisakah saya tetap mengeksposnya melalui properti publik tetapi dengan logika yang dikemas dalam get
dan set
? Mengapa saya harus melakukan ini karena memiliki metode penyetel dan pengambil yang berdedikasi (dengan logika pemrosesan dan validasi yang terkait).
sumber
public int Y { get; } = y;
).Jika yang Anda butuhkan hanyalah variabel untuk menyimpan beberapa data:
public string Name { get; set; }
Ingin membuatnya tampak hanya-baca?
public string Name { get; private set; }
Atau bahkan lebih baik ...
private readonly string _name; ... public string Name { get { return _name; } }
Ingin melakukan pengecekan nilai sebelum menetapkan properti?
public string Name { get { return m_name; } set { if (value == null) throw new ArgumentNullException("value"); m_name = value; } }
Secara umum, GetXyz () dan SetXyz () hanya digunakan dalam kasus tertentu, dan Anda hanya perlu menggunakan naluri saat dirasa tepat. Secara umum, saya akan mengatakan bahwa saya mengharapkan sebagian besar properti get / set tidak mengandung banyak logika dan memiliki sangat sedikit, jika ada, efek samping yang tidak terduga. Jika membaca nilai properti memerlukan pemanggilan layanan atau mendapatkan input dari pengguna untuk membangun objek yang saya minta, maka saya akan menggabungkannya ke dalam metode, dan menyebutnya seperti
BuildXyz()
, bukanGetXyz()
.sumber
myList.Add()
, misalnya (selama objek terekspos untuk berubah, itu bisa berubah).Min
/Max
. Anda ingin memastikannyaMax > Min
? MemilikiSetRange(Min, Max)
kekuatan masuk akal, tetapi bagaimana Anda akan membaca kembali nilai-nilai itu? Properti Min / Max Hanya Baca? Melempar pengecualian untuk masukan yang tidak valid sepertinya cara terbersih untuk menangani ini.Gunakan properti di C #, bukan metode get / set. Mereka ada untuk kenyamanan Anda dan itu idiomatis.
Adapun dua contoh C # Anda, yang satu hanyalah gula sintaksis untuk yang lain. Gunakan properti auto jika yang Anda butuhkan hanyalah wrapper sederhana di sekitar variabel instance, gunakan versi lengkap saat Anda perlu menambahkan logika di getter dan / atau setter.
sumber
Di C # mendukung properti untuk mengekspos bidang pribadi untuk get dan / atau set. Formulir yang Anda sebutkan adalah properti otomatis di mana get dan set secara otomatis menghasilkan bidang dukungan pivot tersembunyi untuk Anda.
Saya menyukai properti otomatis jika memungkinkan tetapi Anda tidak boleh melakukan set / get metode pasangan di C #.
sumber
public string Name { get; set; }
Ini hanyalah properti yang diterapkan secara otomatis , dan secara teknis sama dengan properti normal. Bidang dukungan akan dibuat saat kompilasi.
Semua properti pada akhirnya akan diubah menjadi fungsi, sehingga implementasi terkompilasi yang sebenarnya pada akhirnya sama seperti yang biasa Anda lakukan di Java.
Gunakan properti yang diimplementasikan secara otomatis saat Anda tidak perlu melakukan operasi khusus di bidang dukungan. Gunakan properti biasa jika tidak. Gunakan fungsi get dan setel saat operasi memiliki efek samping atau mahal secara komputasi, gunakan properti jika tidak.
sumber
Terlepas dari cara mana yang Anda pilih di C #, hasil akhirnya sama. Anda akan mendapatkan variabel backinng dengan metode pengambil dan penyetel yang terpisah. Dengan menggunakan properti, Anda mengikuti praktik terbaik dan jadi ini soal seberapa panjang Anda ingin mendapatkannya.
Secara pribadi saya akan memilih properti otomatis, versi terakhir:,
public string Name { get; set; }
karena properti tersebut menggunakan paling sedikit ruang. Dan Anda selalu dapat mengembangkannya di masa mendatang jika Anda perlu menambahkan sesuatu seperti validasi.sumber
Jika memungkinkan, saya lebih suka publik
string Name { get; set; }
karena singkat dan mudah dibaca. Namun, ada kalanya hal ini diperlukanprivate string name; public string Name { get { return name; } set { name = value; } }
sumber
Dalam C # cara yang lebih disukai adalah melalui properti daripada
getX()
dansetX()
metode. Juga, perhatikan bahwa C # tidak mengharuskan properti memiliki get dan set - Anda dapat memiliki properti get-only dan properti set-only.public boolean MyProperty { get { return something; } } public boolean MyProperty { set { this.something = value; } }
sumber
Pertama izinkan saya mencoba menjelaskan apa yang Anda tulis:
// private member -- not a property private string name; /// public method -- not a property public void setName(string name) { this.name = name; } /// public method -- not a property public string getName() { return this.name; } // yes it is property structure before .Net 3.0 private string name; public string Name { get { return name; } set { name = value; } }
Struktur ini juga digunakan saat ini tetapi paling cocok jika Anda ingin melakukan beberapa fungsionalitas tambahan, misalnya ketika nilai ditetapkan, Anda dapat mengurai untuk memanfaatkannya dan menyimpannya di anggota pribadi untuk mengubah penggunaan internal.
Dengan .net framework 3.0
// this style is introduced, which is more common, and suppose to be best public string Name { get; set; } //You can more customize it public string Name { get; private set; // means value could be set internally, and accessed through out }
Semoga Anda lebih beruntung di C #
sumber
Seperti disebutkan, semua pendekatan ini menghasilkan hasil yang sama. Yang paling penting adalah Anda memilih konvensi dan mematuhinya. Saya lebih suka menggunakan dua contoh properti terakhir.
sumber
seperti kebanyakan jawaban di sini, gunakan properti Otomatis. Intuitif, lebih sedikit baris kode dan lebih bersih. Jika Anda harus membuat kelas Anda berseri, tandai kelas
[Serializable]
/ dengan[DataConract]
atribut. Dan jika Anda menggunakan[DataContract]
tandai anggota dengan[DataMember(Name="aMoreFriendlyName")] public string Name { get; set; }
Penyetel pribadi atau publik tergantung pada preferensi Anda.
Perhatikan juga bahwa properti otomatis memerlukan getter dan setter (publik atau pribadi).
/*this is invalid*/ public string Name { get; /* setter omitted to prove the point*/ }
Alternatifnya, jika Anda hanya ingin mendapatkan / menyetel, buat bidang pendukung sendiri
sumber
Saat menggunakan properti, ada satu peringatan yang belum disebutkan: Dengan properti, Anda tidak dapat memiliki parameterisasi getter atau setter.
Misalnya bayangkan Anda ingin mengambil item daftar dan ingin juga menerapkan filter pada saat yang bersamaan. Dengan metode get, Anda dapat menulis sesuatu seperti:
obj.getItems(filter);
Sebaliknya, dengan properti Anda terpaksa harus mengembalikan semua barang terlebih dahulu
obj.items
lalu terapkan filter di langkah berikutnya atau Anda harus menambahkan properti khusus yang mengekspos item yang difilter menurut kriteria berbeda, yang segera membengkak API Anda:
obj.itemsFilteredByX obj.itemsFilteredByY
Apa yang terkadang bisa menjadi gangguan adalah ketika Anda memulai dengan sebuah properti, misalnya
obj.items
dan kemudian menemukan bahwa parameter-pengambil atau penyetel diperlukan atau akan mempermudah pengguna API kelas. Anda sekarang perlu menulis ulang API Anda dan mengubah semua tempat di kode Anda yang mengakses properti ini atau mencari solusi alternatif. Sebaliknya, dengan metode get, misalnyaobj.getItems()
, Anda cukup memperluas tanda tangan metode Anda untuk menerima objek "konfigurasi" opsional, misalnyaobj.getItems(options)
tanpa harus menulis ulang semua tempat yang memanggil metode Anda.Meskipun demikian, properti (diimplementasikan secara otomatis) di C # masih merupakan pintasan yang sangat berguna (karena berbagai alasan yang disebutkan di sini) karena sebagian besar waktu parametrikisasi mungkin tidak diperlukan - tetapi peringatan ini tetap berlaku.
sumber