Numaralandırma ve eşleşen özellik için C # adlandırma kuralı


94

Sık sık kendimi bir sıralama olarak bir tür kendi status özelliğini koruyan bir sınıf uygularken buluyorum: Durum numaram ve Durum türünde BİR Durum özelliğim var. Bu isim çatışmasını nasıl çözmeliyim?

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(); }
  }
}

Durum sıralaması farklı türlerde ortak olsaydı, onu sınıfın dışına koyardım ve sorun çözülürdü. Ancak Durum, Araba için geçerlidir, bu nedenle sıralamayı sınıfın dışında ilan etmek mantıklı değildir.

Bu durumda hangi adlandırma kuralını kullanıyorsunuz?

Not: Bu soru, bu sorunun cevabının yorumlarında kısmen tartışıldı . O değildi yana ana soru, çok daha görünürlük alamadım.

DÜZENLEME: Filip Ekberg, belirli 'Durum' durumu için mükemmel bir IMO çözümü öneriyor. Enum / mülkün adı Michael Prewecki en olduğu gibi, farklı olduğu Oysa ben çözümlerini okumak için ilginç olurdu cevap .

DÜZENLEME2 (Mayıs 2010): Benim favori çözümüm, Chris S. tarafından önerildiği gibi, numaralandırma türü adını çoğul hale getirmektir. MS yönergelerine göre, bu yalnızca bayrak numaralandırmaları için kullanılmalıdır. Ama ben bundan daha çok hoşlanmaya başladım. Şimdi bunu normal numaralandırmalar için de kullanıyorum.


1
Sıralamayı sınıfınızın içine yerleştirmek istiyorsanız, bunun için pek çok iyi çözüm olduğunu düşünmüyorum. Aslında sıralamayı ayrı tutmayı tercih ederim, o zaman bu bir sorun oluşturmaz, ancak onu iç içe geçirmekle ilgili düşüncenizi felsefi olarak görebiliyorum.
Craig Shearer

Yanıtlar:


32

Tartışmaya 1 euro ekleyeceğim ama muhtemelen yeni bir şey eklemiyor.

Bariz çözüm, Durumu iç içe geçmiş Enum olmaktan çıkarmaktır. Çoğu .NET numaralandırması (muhtemelen Windows.Forms ad alanındaki bazıları dışında) yuvalanmaz ve API'nizi kullanan geliştiricinin sınıf adını önek olarak alması sinir bozucu hale getirir.

Bahsedilmeyen bir şey, MSDN yönergelerine göre bayrak numaralandırmalarının muhtemelen zaten bildiğiniz çoğullaştırılmış isimler olması gerektiğidir (Durum basit bir numaralandırmadır, bu nedenle tekil isimler kullanılmalıdır).

State (Devlet olarak adlandırılan enum) sözdür, "Statü", İngilizce'nin çoğu dilimiz gibi Latince'den aldığı bir ismin aday ifadesidir. Vocative, durumu için bir isim verdiğiniz şeydir ve aday, fiilin konusudur.

Diğer bir deyişle, araba hareket ettiğinde , bu fiildir - hareket onun durumudur. Ama araba çalışmıyor, motoru çalışıyor. Çalışmıyor, motor çalışıyor (muhtemelen burada bir örnek seçtiniz, bu yüzden bu alakasız olabilir).

public class Car
{
  VehicleState _vehicleState= VehicleState.Stationary;

  public VehicleState VehicleState 
  {
    get { return _vehicleState; }
    set { _vehicleState = value; DoSomething(); }
  }
}

public enum VehicleState
{
    Stationary, Idle, Moving
}

Devlet o kadar genelleştirilmiş bir isim ki, hangi duruma atıfta bulunduğunu açıklamak daha iyi olmaz mıydı? Yukarıda yaptığım gibi

Benim görüşümdeki tür örneği okuyucu türüne değil, veritabanına atıfta bulunur. Okuyucunun veritabanı ürününü tanımlıyor olmanızı tercih ederim, ki bu da okuyucu tipiyle ilintili değildir (örneğin, okuyucu tipi sadece ileri, önbelleğe alınmış vb. Olabilir). Yani

reader.Database = Databases.Oracle;

Gerçekte bu, numaralandırmaları kullanmak yerine sürücüler ve miras zinciri olarak uygulandıkları için asla gerçekleşmez ve bu nedenle yukarıdaki satır doğal görünmez.


24
Anladığım kadarıyla bayraklar basit numaralandırmalar değil çoğullaştırılmalıdır.
Serge Wautier

9
Numaralandırmaları sınıfın dışına taşımayla ilgili olarak, CarState'in neden Car.State'ten daha uygun olduğunu henüz anlamadım. Ancak, bu sıralama yalnızca bu sınıfın davranışını açıkladığında, sınıftan bir sıralama almanın olumlu yanını anlamıyorum.
Serge Wautier

Sadece isimler değil, FileOptions gibi isim cümleleri yazmalıydım, cevabı güncelledim. Sanırım classname.Enum sadece bir tercih - kopyalamaya son verdiğim çerçevede herhangi bir örnek bulamıyorum.
Chris S

MS çoğulun bayraklar için saklanması gerektiğini söylese de, zamanla bu çözümleri daha çok sevmeye başladım. Şimdi numaralandırma için de kullanıyorum. Bu yüzden fikrimi değiştirdim ve cevabını Filip'inki yerine kabul ettim.
Serge Wautier

1
Biliyorum burada 1 1/2 yıl geç kaldım, ama örnek public class EngineStateolmalı public enum EngineState, değil mi?
David Murdoch

36

"Kapalı", "Başlangıç" ve "Hareket" tanımları benim "Durum" dediğim şeydir. Ve bir "Eyalet" kullandığınızı ima ettiğinizde, bu sizin "Durumunuzdur". Yani!

public class Car
{
  public enum State
  {
    Off,
    Starting,
    Moving
  };

  State state = State.Off;

  public State Status
  {
    get { return state ; }
    set { state= value; DoSomething(); }
  }
}

Bu durumda "Tür" kelimesini kullanmak istediğiniz yerde belirtilenlerden başka bir örnek alırsak:

public class DataReader
{
    public enum Type
    {
        Sql,
        Oracle,
        OleDb
    }

    public Type Type { get; set; } // <===== Won't compile =====

}

Numaralandırmalar ve numaralandırmalar arasında bir fark olduğunu gerçekten görmeniz gerekiyor, değil mi? Ancak bir çerçeve oluştururken veya mimari hakkında konuşurken benzerliklere odaklanmanız gerekir, tamam onları bulalım:

Bir şey bir Duruma ayarlandığında, "şeyler" Durumu olarak tanımlanır

Örnek: Aracın Durumu Çalışıyor Durumda, Durdurulmuş Durumda vb.

İkinci örnekte elde etmek istediğiniz şey bir şekilde şudur:

myDataReader.Type = DataReader.Database.OleDb

Bunun, başkalarına vaaz ettiğim şeye aykırı olduğunu, bir standardı takip etmeniz gerektiğini söylediğini düşünebilirsiniz. Ancak, bir standardı takip ediyorsunuz! Sql vakası da özel bir durumdur ve bu nedenle biraz spesifik bir çözüme ihtiyaç duyar.

Bununla birlikte, sıralama, System.Dataalanınızda yeniden kullanılabilir ve kalıpların tamamı da budur.

"Tür" ile bakılması gereken başka bir durum, Türün Türleri tanımladığı "Hayvan" dır.

public class Animal
    {
        public enum Type
        {
            Mammal,
            Reptile,
            JonSkeet
        }

        public Type Species{ get; set; }

    }

Bu bir kalıbı takip ediyor, bunun için Nesneyi "bilmeniz" gerekmiyor ve "AnimalType" veya "DataReaderType" ı belirtmiyorsanız, isim alanınızdaki numaralandırmaları yeniden kullanabilirsiniz.


2
"Durum" adının sadece bir örnek olduğuna inanıyorum. Statü / Duruma güvenemediğiniz diğer durumlar ne olacak? Örneğin bir Tür sıralaması ...
Dan C.

2
@Filip: Hayvan Türü örneği, ilk yorumda tam olarak ne demek istediğimi gösteriyor, yani bu, numaralandırmanın hemen hemen "yeniden yazılması". Numaralandırma ve özellik adı için eşanlamlılar kullanmak kodu biraz kafa karıştırıcı hale getiriyor, sanırım.
Dan C.

1
Bence 'türler' sadece bir tür yeniden ifade etmektir (bu durumda hayvanlar için).
LegendLength

2
Basitçe yeniden adlandırmak her zaman o kadar temiz değildir - örneğin bir enum Suit ve bir özellikli Suit içeren bir oyun kartı için bir sınıf düşünün - tam olarak neye yeniden adlandırın? Her iki durumda da sakar.
annakata

1
bu yaklaşım yanlış anlamaya yol açıyor ve kodu karıştırıyor
Boogier,

9

Ben öyle ki, burada asıl sorun enum Durumu senin sınıf içinde kapsüllü olduğunu düşünüyorum Car.Statusmülkiyet hem de belirsiz Statusve enumStatus

Daha da iyisi, numaranızı sınıfın dışına koyun:

public enum Status
{
    Off,
    Starting,
    Moving
}

public class Car
{
    public Status Status
    { ... }
}

GÜNCELLEME

Aşağıdaki yorumlar nedeniyle tasarımımı yukarıda açıklayacağım.

Ben Çeteleler veya sınıflar veya başka herhangi bir nesne bulunması gerektiğine inanmıyor biriyim içeride o sınıfın içinde tamamen özel olacak olmadıkça, başka bir sınıfa. Örneğin yukarıdaki örneği ele alalım:

public class Car
{
    public enum Status
    {...}
    ...
    public Status CarStatus { get; set;}
}

Bu durumu iddia ediyorum bazı yorum yapanlar sınıf Car kapsamı dışında herhangi bir anlamı olmasa da, bir ayarlarken olması kamu programın diğer kısımları vardır mülkiyet araçlarını olacak o enum kullanın:

public Car myCar = new Car();
myCar.CarStatus = Car.Status.Off;

Ve bu benim için bir kod kokusu. O durum bakmaya gidiyorum varsa dışarıdan ait Car, benim de tanımlayabilirsiniz dışında da.

Bu nedenle, muhtemelen şu şekilde yeniden adlandıracağım:

public enum CarStatus
{...}

public class Car
{
    ...
    public CarStatus Status { get; set; }
}

Ancak, bu sıralama yalnızca araba sınıfı içinde ve içinde kullanılacaksa , sıralamayı orada beyan etmekte sorun yok.


Bu Durum'u global yapar, sadece belirli bir alanda olmasını isteyebilirsiniz. "İnsan" gibi diğer türler için "Durum", "Başlıyor" olmayabilir. Ama bir model izlemelisin.
Filip Ekberg

Hayır o yerinde. Numaralandırma, vakaların% 99'unda özellik için kullanmak istediğiniz aynı sözcüktür. Enum sadece adlandırılmış bir bayraktır, bu yüzden dışarıda yaşarken çok az zarar verir (mantık içeren sınıfların aksine)
Quibblesome

Jon, bu kesinlikle benim fikrim: Durum sıralaması sadece Araba için anlamsız. Tamamen farklı türdeki nesnelerin tamamen farklı durumları olacaktır
Serge Wautier

ancak farklı ad alanlarında olacaklar, bu yüzden önemli olmayacak
Chris S

Ona Araba dışında bakmak istemenin açıklaması mantıklı. Ama benim durumumda iki sınıfım var ORve CR. Her ikisinin de kendi durumları vardır, bu yüzden onları kendi kapsamlarının dışında tanımlama seçeneği değildir.
deed02392

4

Önerimin. Bunun neden bir sözleşme olmadığını gerçekten anlamıyorum. Numaralandırmalar / Bayraklar, türlerini asla değiştirmeyecek Arayüzler gibi özel bir durumdur. Sadece ne olduğunu açıklığa kavuşturmakla kalmaz, aynı zamanda intellisense yazmak çok kolaydır çünkü önek diğer türlerin / değişkenlerin / vb. Çoğunu filtreleyecektir ve bu adlandırma çakışmalarına sahip olmayacaksınız.

Ve bu, WPF'deki örnekler için önceden tanımlanmış tür örneklerine sahip olan ancak onu aramayıp aramayacağınızı bilemeyeceğiniz numaralandırma gibi statik sınıfları (örneğin FontWeights) kullandıkları başka bir sorunu da çözecektir. Onlara sadece 'E' ekledilerse, bu özel statik sınıfları bulmak için tek yapmanız gereken karakterin üzerine yazmaktır.


4

Macar notasyonundan nefret edenler ve çeşitleri lanetlenecek. - Bekleyin - ile son ek numaralandırma kuralı kullanıyorum Enum. Sonuç olarak tarif ettiğiniz problemi asla yaşamıyorum, onlara ne isim vereceğiniz konusunda endişelenerek zaman harcıyorum ve kod okunabilir ve önyükleme için kendi kendini açıklayıcı.

public class Car
{
  public enum StatusEnum
  {
    Off,
    Starting,
    Moving
  };

  public StatusEnum Status { get; set; }

}

9
Lütfen Microsoft'un Numaralandırmaları Adlandırma kurallarının şunu söylediğine dikkat edin: X , numara türü adlarında "Enum" soneki
DavidRR

2
Çünkü Microsoft'un sözleşmelerinin zamanın testine dayandığı kanıtlanmıştır.
nathanchere

2

Özelliğin adını "CurrentStatus" gibi bir şeye değiştirirdim. Hızlı ve kolay :)


1

Tür adına "Option" (veya bit bayrakları içeriyorsa Flag) eklemenizi öneririm, yani type Car.StatusOption ve özellik Car.Status'tur.

Çoğullaştırma ile karşılaştırıldığında, bu, normal olarak enum türünü değil, koleksiyon özelliğini çoğul hale getirmek isteyeceğiniz enum türünün koleksiyonlarını oluştururken ad çakışmalarını önler .


0

Genellikle numaralandırmaların önüne eklerim, örneğin CarStatus. Sanırım hepsi birlikte çalıştığınız ekibe (bu tür şeyler için herhangi bir kuralları / süreçleri varsa) ve nesnelerin kullanımına bağlı. Sadece 2 sentim (:


1
Bu, MyObjectName'in Status'un önüne geçtiği Adlandırma kuralını gerçekten öldürür.
Filip Ekberg

sınıftan ad alanlarının gerektiğini bu zaten başa çıkmak için yeterli olacak
annakata
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.