私は、自分自身のステータスプロパティを列挙型として保持するクラスを実装していることがよくあります。Status型とStatus型の1つのStatusプロパティがあります。この名前の競合をどのように解決すればよいですか?
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(); }
}
}
Status列挙型がさまざまなタイプに共通している場合、クラスの外に配置すると問題が解決します。ただし、StatusはCarにのみ適用されるため、クラスの外で列挙型を宣言することは意味がありません。
この場合、どのような命名規則を使用しますか?
NB:この質問は この質問 の回答のコメントで部分的に議論されました。 mainの質問ではなかったので、あまり目立ちませんでした。
編集:Filip Ekbergは、「状況」の特定のケースに対するIMOの優れた回避策を提案しています。それでも、Michael Preweckiのanswerのように、enum/propertyの名前が異なるソリューションについて読むのは面白いでしょう。
EDIT2(2010年5月):私のお気に入りのソリューションは、Chris Sによって提案された列挙型名を複数化することです。MSガイドラインによると、これはフラグ列挙にのみ使用する必要があります。しかし、私はそれをますます好きになりました。今では、通常の列挙にも使用しています。
ディスカッションに1ユーロを追加しますが、おそらく新しいものは追加されません。
明らかな解決策は、StatusをネストされたEnumから移動することです。ほとんどの.NET列挙型(Windows.Forms名前空間の一部を除く)はネストされていないため、クラス名にプレフィックスを付ける必要があるため、APIを使用する開発者が使用するのが面倒です。
言及されていないことの1つは、MSDNガイドラインによるフラグ列挙型は 複数形の名詞 であることです。 (ステータスは単純な列挙型なので、単数形の名詞を使用する必要があります)。
状態(状態と呼ばれる列挙)は呼応的であり、「状態」は、英語が私たちのほとんどの言語のようにラテン語から吸収した名詞の主格です。動詞はその状態を表す名詞の名前であり、主格は動詞の主題です。
つまり、車が動いているとき、それが動詞です-動いているのがその状態です。しかし、車は止まらず、エンジンも止まります。また、エンジンも起動しません(おそらくここで例を選んだので、これは無関係かもしれません)。
public class Car
{
VehicleState _vehicleState= VehicleState.Stationary;
public VehicleState VehicleState
{
get { return _vehicleState; }
set { _vehicleState = value; DoSomething(); }
}
}
public enum VehicleState
{
Stationary, Idle, Moving
}
状態はそのような一般化された名詞であり、それがどの状態を指しているのかを説明する方が良いでしょうか?上記のように
私の見解でもタイプの例は、リーダーのタイプではなく、そのデータベースを参照しています。読者の種類に必ずしも関係しない読者のデータベース製品を説明している場合は、それをお勧めします(たとえば、読者の種類は転送のみ、キャッシュなど)。そう
reader.Database = Databases.Oracle;
実際には、列挙型を使用する代わりにドライバーおよび継承チェーンとして実装されているため、これは決して起こりません。これが、上の行が自然に見えない理由です。
「オフ」、「開始」、「移動」の定義は、「状態」と呼ばれるものです。そして、あなたが「州」を使用していることを暗示しているとき、それはあなたの「状態」です。そう!
public class Car
{
public enum State
{
Off,
Starting,
Moving
};
State state = State.Off;
public State Status
{
get { return state ; }
set { state= value; DoSomething(); }
}
}
この場合、「Type」という単語を使用したいところから別の例を取り上げると、
public class DataReader
{
public enum Type
{
Sql,
Oracle,
OleDb
}
public Type Type { get; set; } // <===== Won't compile =====
}
列挙型と列挙型には違いがあることを本当に確認する必要がありますよね?しかし、フレームワークを作成するときやアーキテクチャについて話すときは、類似点に集中する必要があります。
何かが状態に設定されると、「もの」ステータスとして定義されます
例:車のステータスは、実行状態、停止状態などです。
2番目の例で達成したいのは、これです。
myDataReader.Type = DataReader.Database.OleDb
これは、私が他の人に説教してきたことに対して、標準に従う必要があると言っていると思うかもしれません。しかし、あなたは標準に従っています! Sql-caseも特定のケースであるため、ある程度具体的なソリューションが必要です。
ただし、列挙型はSystem.Data
スペース内で再利用でき、それがパターンの目的です。
「タイプ」で見るもう1つのケースは、タイプが種を定義する「動物」です。
public class Animal
{
public enum Type
{
Mammal,
Reptile,
JonSkeet
}
public Type Species{ get; set; }
}
これはパターンに従っています。特にオブジェクトを「知る」必要はなく、「AnimalType」または「DataReaderType」を指定せず、選択したネームスペースで列挙を再利用できます。
ここでの本当の問題は、列挙型Statusがクラス内にカプセル化されているため、Car.Status
は、プロパティStatus
とenum Status
の両方に対してあいまいです
さらに良いことに、enumをクラスの外に置きます:
public enum Status
{
Off,
Starting,
Moving
}
public class Car
{
public Status Status
{ ... }
}
[〜#〜] update [〜#〜]
以下のコメントにより、上記の設計について説明します。
私は、列挙またはクラスまたは他のオブジェクトがそのクラス内で完全にプライベートでない限り、別のクラスにinside存在することを信じていない人です。たとえば、上記の例を見てください。
public class Car
{
public enum Status
{...}
...
public Status CarStatus { get; set;}
}
一部のコメンテーターは、ステータスがクラスCarの範囲外では意味を持たないと主張しますが、publicプロパティを設定しているという事実は、 がその列挙型を使用するプログラムの他の部分があります。
public Car myCar = new Car();
myCar.CarStatus = Car.Status.Off;
そして、thatは私にとってコードの匂いです。 Car
のステータスoutsideを見る場合、定義することもできますoutsideも同様です。
そのため、おそらく次のように名前を変更します。
public enum CarStatus
{...}
public class Car
{
...
public CarStatus Status { get; set; }
}
ただし、その列挙型が車クラス内でのみ使用される場合、そこで列挙型を宣言しても問題ありません。
ハンガリー記法の嫌悪とその変種はとてつもない。列挙型の接尾辞の規則を使用します-それを待ちます-Enum
。その結果、私はあなたが説明する問題を抱えることはなく、それらを何と呼ぶかを心配する時間を無駄にし、コードは読みやすく、ブートするのに自己記述的です。
public class Car
{
public enum StatusEnum
{
Off,
Starting,
Moving
};
public StatusEnum Status { get; set; }
}
私の提案は.NETの命名規則に反することは知っていますが、個人的に列挙型には「E」を、列挙型フラグには「F」を付けます(インターフェイスに「I」を付ける方法と同様)。これが慣例ではない理由を私は本当に理解していません。列挙型/フラグは、タイプを変更しないインターフェイスのような特殊なケースです。それが何であるかを明確にするだけでなく、接頭辞が他のほとんどのタイプ/変数/などをフィルタリングするため、インテリセンスで非常に簡単に入力でき、これらの名前の衝突はありません。
また、WPFの例では、型の定義済みインスタンスを含む列挙型(FontWeightsなど)のような静的クラスを使用するが、検索しない場合はわからないという別の問題も解決します。 「E」をプレフィックスとして付けただけの場合、文字を入力するだけでこれらの特別な静的クラスを見つけることができます。
プロパティの名前を「CurrentStatus」などに変更します。クイック簡単:)
タイプ名(またはビットフラグが含まれる場合はフラグ)に「オプション」を追加することをお勧めします。つまり、タイプはCar.StatusOptionであり、プロパティはCar.Statusです。
複数形化と比較して、これは通常、enum typeではなく、コレクションpropertyを複数形化する列挙型のコレクションを作成する際の名前の衝突を回避します。
通常、列挙型のプレフィックスを付けます。 CarStatus。私はそれがすべてあなたが働いているチーム(その種のもののためのルール/プロセスを持っている場合)とオブジェクトの使用法に依存すると思います。ちょうど私の2セント(: