Saya sering menemukan diri saya menerapkan kelas yang mempertahankan beberapa jenis properti status sendiri sebagai enum: Saya memiliki Status enum dan SATU properti Status tipe Status. Bagaimana cara mengatasi konflik nama ini?
public class Car
{
public enum Status
{
Off,
Starting,
Moving
};
Status status = Status.Off;
public Status Status // <===== Won't compile =====
{
get { return status; }
set { status = value; DoSomething(); }
}
}
Jika Status enum umum untuk jenis yang berbeda, saya akan meletakkannya di luar kelas dan masalahnya akan terpecahkan. Tetapi Status hanya berlaku untuk Mobil sehingga tidak masuk akal untuk mendeklarasikan enum di luar kelas.
Konvensi penamaan apa yang Anda gunakan dalam kasus ini?
NB: Pertanyaan ini sebagian diperdebatkan dalam komentar dari jawaban pertanyaan ini . Karena ini bukan pertanyaan utama , maka tidak banyak terlihat.
EDIT: Filip Ekberg menyarankan solusi IMO yang sangat baik untuk kasus khusus 'Status'. Namun saya akan tertarik untuk membaca tentang solusi di mana nama enum / properti berbeda, seperti dalam jawaban Michael Prewecki .
EDIT2 (Mei 2010): Solusi favorit saya adalah menjumlahkan nama jenis enum, seperti yang disarankan oleh Chris S. Menurut pedoman MS, ini harus digunakan hanya untuk enum bendera. Tapi aku semakin menyukainya. Saya sekarang menggunakannya untuk enum biasa juga.
sumber
Jawaban:
Saya akan menambahkan 1 euro saya ke diskusi tetapi mungkin tidak menambahkan sesuatu yang baru.
Solusi yang jelas adalah memindahkan Status menjadi Enum bersarang. Sebagian besar .NET enum (kecuali mungkin beberapa di namespace Windows.Forms) tidak bersarang dan membuatnya mengganggu digunakan untuk pengembang yang mengonsumsi API Anda, harus mengawali nama kelas.
Satu hal yang belum disebutkan adalah bahwa enum flag menurut pedoman MSDN harus berupa kata benda jamak yang mungkin sudah Anda ketahui (Status adalah enum sederhana sehingga kata benda tunggal harus digunakan).
State (enum disebut States) adalah vocative, "Status" adalah nominatif dari kata benda yang bahasa Inggris seperti kebanyakan bahasa kita serap dari bahasa Latin. Vocative adalah nama kata benda untuk kondisinya dan nominatif adalah subjek dari kata kerja.
Jadi dengan kata lain saat mobil bergerak , itulah kata kerjanya - bergerak adalah statusnya. Tapi mobilnya tidak mati, mesinnya mati. Juga tidak menyala, mesin tidak (Anda mungkin memilih contoh di sini jadi ini mungkin tidak relevan).
public class Car { VehicleState _vehicleState= VehicleState.Stationary; public VehicleState VehicleState { get { return _vehicleState; } set { _vehicleState = value; DoSomething(); } } } public enum VehicleState { Stationary, Idle, Moving }
Negara adalah kata benda yang digeneralisasikan, bukankah lebih baik untuk menggambarkan keadaan yang dimaksud? Seperti yang saya lakukan di atas
Contoh tipe juga dalam pandangan saya tidak merujuk ke tipe pembaca, tetapi database-nya. Saya lebih suka jika Anda mendeskripsikan produk database pembaca yang belum tentu relevan dengan jenis pembaca (misalnya, jenis pembaca mungkin hanya maju, disimpan dalam cache, dan sebagainya). Begitu
Pada kenyataannya ini tidak pernah terjadi karena mereka diimplementasikan sebagai driver dan rantai warisan alih-alih menggunakan enum, itulah sebabnya baris di atas tidak terlihat alami.
sumber
public class EngineState
harus menjadipublic enum EngineState
contoh, bukan?Definisi dari "Off", "Starting" dan "Moving" adalah apa yang saya sebut sebagai "State". Dan ketika Anda menyiratkan bahwa Anda menggunakan "Status", itu adalah "Status" Anda. Begitu!
public class Car { public enum State { Off, Starting, Moving }; State state = State.Off; public State Status { get { return state ; } set { state= value; DoSomething(); } } }
Jika kita mengambil contoh lain dari yang dinyatakan di mana Anda ingin menggunakan kata "Type" seperti dalam kasus ini:
public class DataReader { public enum Type { Sql, Oracle, OleDb } public Type Type { get; set; } // <===== Won't compile ===== }
Anda benar-benar perlu melihat bahwa ada perbedaan antara enum dan enum, bukan? Tetapi ketika membuat kerangka kerja atau berbicara tentang arsitektur, Anda perlu fokus pada kesamaan, ok mari kita temukan:
Ketika sesuatu diatur ke Status, itu didefinisikan sebagai Status "hal"
Contoh: Status Mobil dalam Status Berjalan, Status Berhenti, dan sebagainya.
Apa yang ingin Anda capai dalam contoh kedua adalah sebagai berikut:
Anda mungkin berpikir bahwa ini mengatakan bertentangan dengan apa yang telah saya khotbahkan kepada orang lain, bahwa Anda harus mengikuti standar. Tapi, Anda mengikuti standar! Kasus Sql adalah kasus khusus juga dan oleh karena itu membutuhkan solusi yang agak spesifik.
Namun, enum akan dapat digunakan kembali di dalam
System.Data
ruang Anda , dan itulah inti dari polanya.Kasus lain untuk dilihat dengan "Type" adalah "Animal" dimana Type mendefinisikan Species.
public class Animal { public enum Type { Mammal, Reptile, JonSkeet } public Type Species{ get; set; } }
Ini mengikuti pola, Anda tidak perlu secara khusus "mengetahui" Objek untuk ini dan Anda tidak menentukan "AnimalType" atau "DataReaderType", Anda dapat menggunakan kembali enum di ruang nama pilihan Anda.
sumber
Saya pikir masalah sebenarnya di sini adalah bahwa Status enum dienkapsulasi dalam kelas Anda, sedemikian rupa sehingga
Car.Status
ambigu baik untuk propertiStatus
maupun enumStatus
Lebih baik lagi, letakkan enum Anda di luar kelas:
public enum Status { Off, Starting, Moving } public class Car { public Status Status { ... } }
MEMPERBARUI
Karena komentar di bawah, saya akan menjelaskan desain saya di atas.
Saya salah satu yang tidak percaya bahwa enum atau kelas atau objek lain harus berada di dalam kelas lain, kecuali jika itu akan benar-benar pribadi dalam kelas itu. Ambil contoh di atas, misalnya:
public class Car { public enum Status {...} ... public Status CarStatus { get; set;} }
Sementara beberapa komentator akan berpendapat bahwa Status tidak memiliki arti apa pun di luar cakupan kelas Mobil, fakta bahwa Anda menyetel properti publik berarti ada bagian lain dari program yang akan menggunakan enum itu:
public Car myCar = new Car(); myCar.CarStatus = Car.Status.Off;
Dan yang bagi saya adalah kode bau. Jika aku akan melihat bahwa status luar dari
Car
, saya mungkin juga mendefinisikannya luar juga.Karena itu, saya mungkin akan mengganti namanya menjadi:
public enum CarStatus {...} public class Car { ... public CarStatus Status { get; set; } }
Namun, jika enum itu akan digunakan di dalam dan hanya di dalam kelas mobil, maka saya baik-baik saja dengan menyatakan enum tersebut di sana.
sumber
OR
danCR
. Keduanya memiliki kumpulan statusnya sendiri, jadi ini bukan opsi untuk menentukannya di luar cakupannya sendiri.Saya tahu saran saya bertentangan dengan konvensi Penamaan .NET, tetapi saya secara pribadi mengawali enum dengan 'E' dan enum flag dengan 'F' (mirip dengan cara kita mengawali Antarmuka dengan 'I'). Saya benar-benar tidak mengerti mengapa ini bukan konvensi. Enums / Flags adalah kasus khusus seperti Antarmuka yang tidak akan pernah mengubah tipenya. Tidak hanya memperjelas apa itu, sangat mudah untuk mengetikkan intellisense karena awalan akan memfilter sebagian besar jenis / variabel / dll, dan Anda tidak akan mengalami bentrokan penamaan ini.
Dan itu juga akan memecahkan masalah lain di mana untuk contoh di WPF mereka menggunakan kelas statis seperti enum (misalnya FontWeights) yang memiliki contoh tipe yang telah ditentukan tetapi Anda tidak akan tahu jika Anda tidak mencarinya. Jika mereka hanya memberi awalan dengan 'E', yang harus Anda lakukan adalah mengetik karakter untuk menemukan kelas statis khusus ini.
sumber
Pembenci notasi Hongaria dan variannya terkutuk. Saya menggunakan konvensi sufiks enum dengan - tunggu -
Enum
. Akibatnya saya tidak pernah memiliki masalah yang Anda gambarkan, buang waktu mengkhawatirkan tentang apa yang harus memanggil mereka dan kode dapat dibaca dan deskriptif sendiri untuk boot.public class Car { public enum StatusEnum { Off, Starting, Moving }; public StatusEnum Status { get; set; } }
sumber
Saya akan mengubah nama properti menjadi sesuatu seperti "CurrentStatus". Cepat dan mudah :)
sumber
Saya sarankan untuk menambahkan "Option" ke nama tipe (atau Flag jika mengandung bit flag), yaitu tipe Car.StatusOption dan propertinya adalah Car.Status.
Dibandingkan dengan pluralisasi, ini menghindari benturan penamaan saat membuat koleksi dari jenis enum, di mana Anda biasanya ingin membuat jamak properti collection , bukan jenis enum .
sumber
Saya biasanya mengawali enum, misalnya CarStatus. Saya kira itu semua tergantung pada tim tempat Anda bekerja (jika mereka memiliki aturan / proses untuk hal semacam itu) dan penggunaan objek. Hanya 2 sen saya (:
sumber