一般に、特定の列挙型をパラメーターとして受け取る単一の型または名前空間が存在することがわかりました。その結果、常にそれらの列挙型を定義してきました。しかし最近、私は同僚に、それがいかに愚かなことであるかについて大騒ぎしました。プロジェクトのルートには、すべての列挙型を定義する列挙型名前空間を常に配置する必要があります。
列挙型を見つけるのに最適な場所はどこですか?
一般に、特定の列挙型をパラメーターとして受け取る単一の型または名前空間が存在することがわかりました。その結果、常にそれらの列挙型を定義してきました。しかし最近、私は同僚に、それがいかに愚かなことであるかについて大騒ぎしました。プロジェクトのルートには、すべての列挙型を定義する列挙型名前空間を常に配置する必要があります。
列挙型を見つけるのに最適な場所はどこですか?
列挙型を他の型とは異なる方法で扱うのはなぜですか? 使用される可能性が高いのと同じ名前空間にそれらを保持します。また、他のクラスで使用されると想定して、独自のファイルのトップレベルの型にします。
私が一般的にまとめているタイプはデリゲートだけです。デリゲートの束を含む Delegates.cs ファイルを持っていることがあります。.NET 3.5 と Func/Action ではそうではありません。
また、名前空間は、論理的に一緒に属するものを分離するためのものです。クラスであるという理由だけで、すべてのクラスが同じ名前空間に属しているわけではありません。同様に、列挙型であるという理由だけで、すべての列挙型が同じ名前空間に属しているわけではありません。それらが論理的に属するコードでそれらを配置します。
クラスに関連するすべてのものをクラスに入れようとします。これには、列挙型だけでなく、定数も含まれます。列挙型を含むファイルまたはクラスを他の場所で検索したくありません。多数のクラスとフォルダーを含む大規模なアプリでは、列挙型ファイルをどこに置くかが常に明確であるとは限らないため、簡単に見つけることができます。
列挙型が密接に関連するいくつかのクラスで使用されている場合、列挙型のような共通の型がそこで共有されるように基本クラスを作成できます。
もちろん、enum が本当に一般的で広く使用されている場合は、他の一般的なユーティリティと一緒に別のクラスを作成することもできます。
列挙型と定数を、それらを消費するクラス、またはそれらを使用してコードの決定を最も制御するクラスに配置し、コード補完を使用してそれらを見つけると思います。そうすれば、それらがどこにあるかを覚えておく必要はありません。それらはクラスに関連付けられています。たとえば、ColoredBox クラスがある場合、それらがどこにあるかを考える必要はありません。それらは ColoredBox の一部になります。ColoredBox.Colors.Red、ColoredBox.Colors.Blue など。enum と定数は、そのクラスのプロパティまたは説明と考えています。複数のクラスで使用され、どのクラスも支配しない場合は、enum クラスまたは定数クラスを使用するのが適切です。これは、カプセル化の規則に従います。異なるクラスからのプロパティの分離。Cirle オブジェクトの赤の RGB を変更することに決めたが、変更しなかった場合はどうなるでしょうか? ColoredBox オブジェクトの赤を変更したくないですか? プロパティをカプセル化すると、これが可能になります。
私は通常、さまざまな型 (クラス、インターフェイス、および列挙型) をすべて、それらがどれほど小さいかに関係なく、独自のファイルに入れようとします。特に、たまたま Visual Studio を使用しておらず、「定義に移動」機能を使用できる場合は、それらが含まれているファイルを見つけて管理するのがはるかに簡単になります。そのような「単純な」型を別のクラスに配置するたびに、後で追加するか、そうしないと意味がなくなるような方法で再利用することになることがわかりました。専用のファイルがあります。
どの名前空間に関しては、開発しているものの設計に大きく依存します。一般に、私は .NET フレームワークの規則を模倣しようとしています。
これには、ネストされた名前空間を使用します。MyEnum がスコープ内の他のものと衝突しない場合でも、クラスの外では完全な MyClass::MyEnum の使用法を使用する必要があるため、列挙型をクラス内に配置するよりも好きです。
ネストされた名前空間を使用すると、「using」構文を使用できます。また、特定のサブシステムに関連する列挙型を独自のファイルに配置して、それらを使用するために世界を含める必要があるという依存関係の問題が発生しないようにします。
したがって、enum ヘッダー ファイルでは次のようになります。
// MyEnumHeader.h
// Consolidated enum header file for this dll,lib,subsystem whatever.
namespace MyApp
{
namespace MyEnums
{
enum SomeEnum { EnumVal0, EnumVal1, EnumVal2 };
};
};
そして、クラス ヘッダー ファイルに次のように表示されます。
// MyInterfaceHeader.h
// Class interfaces for the subsystem with all the expected dependencies.
#include "MyEnumHeader.h"
namespace MyApp
{
class MyInterface
{
public:
virtual void DoSomethingWithEnumParam (MyEnums::SomeEnum enumParam) = 0;
};
};
または、理にかなった数の enum ヘッダー ファイルを使用します。私はそれらをクラス ヘッダーとは別にしておくのが好きなので、クラス ヘッダーを必要とせずにシステムの他の場所で列挙型をパラメーターにすることができます。次に、それらを他の場所で使用したい場合は、列挙型がクラス内で宣言されている場合のように、カプセル化されたクラス定義を持つ必要はありません。
前述のように、外側のコードでは次を使用できます。
using namespace MyApp::MyEnums;
どんな環境?
.NET では通常、空のクラス ファイルを作成し、名前を MyEnum などに変更して、列挙型を保持していることを示し、そこで宣言します。
使用する予定のクラスの外で列挙が使用される可能性がある場合は、列挙用に別のソース ファイルを作成します。それ以外の場合は、使用する予定のクラス内に配置します。
通常、列挙型は単一のクラス (MyClassOptions 型のもの) を中心にしていることがわかります。
その場合、列挙型を MyClass と同じファイルに配置しますが、名前空間内でクラスの外に配置します。
namespace mynamespace
{
public partial class MyClass
{
}
enum MyClassOptions
{
}
}
私はそれらを定義する傾向があり、それらの使用が明らかな場合に明らかです。何らかの理由でそれを使用する構造体の typedef がある場合...
typedef enum {
HI,
GOODBYE
} msg_type;
typdef struct {
msg_type type;
union {
int hivar;
float goodbyevar;
}
} msg;