ソリューション内のフォルダーは名前空間と一致する必要がありますか?
-
08-06-2019 - |
質問
ソリューション内のフォルダーは名前空間と一致する必要がありますか?
私のチーム プロジェクトの 1 つには、プロジェクト内に多数のサブフォルダーを含むクラス ライブラリがあります。
プロジェクト名と名前空間: MyCompany.Project.Section
.
このプロジェクト内には、名前空間セクションに一致するフォルダーがいくつかあります。
- フォルダ
Vehicles
にクラスがありますMyCompany.Project.Section.Vehicles
名前空間 - フォルダ
Clothing
にクラスがありますMyCompany.Project.Section.Clothing
名前空間 - 等
この同じプロジェクト内に別の不正なフォルダーがあります
- フォルダ
BusinessObjects
にクラスがありますMyCompany.Project.Section
名前空間
このように、「組織上の利便性」のためにフォルダーが作成されるケースがいくつかあります。
私の質問は次のとおりです。基準は何ですか?クラス ライブラリでは、通常、フォルダーは名前空間構造と一致しますか、それとも混合バッグですか?
解決
また、組み込みテンプレートを使用してクラスをフォルダーに追加すると、デフォルトでフォルダー階層を反映する名前空間にクラスが配置されることに注意してください。
クラスが見つけやすくなる、それだけでも十分な理由になるはずです。
私たちが従うルールは次のとおりです。
- プロジェクト/アセンブリ名は、.dll の末尾を除き、ルート名前空間と同じです。
- 上記のルールの唯一の例外は、.Core で終わるプロジェクトであり、.Core は削除されます。
- フォルダーは名前空間と同等です
- ファイルごとに 1 つのタイプ (クラス、構造体、列挙型、デリゲートなど) により、適切なファイルを簡単に見つけることができます。
他のヒント
いいえ。
私は、小規模プロジェクトと大規模プロジェクトで両方の方法を、単一の開発者 (私) と開発者のチームの両方で試してきました。
最も単純で生産的な方法は、プロジェクトごとに 1 つの名前空間を用意し、すべてのクラスをその名前空間に入れることだと私は思いました。その後、クラス ファイルを任意のプロジェクト フォルダーに自由に配置できます。名前空間は 1 つだけなので、常にファイルの先頭に using ステートメントを追加しても面倒なことはありません。
ソース ファイルをフォルダーに整理することが重要であり、私の意見では、フォルダーはそれだけで使用されるべきです。これらのフォルダーも名前空間にマップすることを要求するのは不必要であり、より多くの作業が発生します。また、追加の負担が組織の混乱を促進するため、実際には組織にとって有害であることがわかりました。
たとえば、次の FxCop 警告を考えてみましょう。
CA1020:タイプが少ない名前空間を避ける
原因:グローバル名前空間以外の名前空間に含まれるタイプが 5 つ未満である https://msdn.microsoft.com/en-gb/library/ms182130.aspx
この警告は、新しいフォルダーの作成を正当化する類似のクラスが 4 つあるまで、新しいファイルを汎用の Project.General フォルダー、またはプロジェクト ルートにダンプすることを奨励します。そんなことは起こるでしょうか?
ファイルの検索
受け入れられた回答は、「クラスが見つけやすくなり、それだけで十分な理由になるはずです。」と述べています。
その答えは、私が提案している単一の名前空間を持つプロジェクトではなく、フォルダー構造にマップされていないプロジェクト内に複数の名前空間があることを指しているのではないかと思います。
いずれの場合も、名前空間からクラス ファイルがどのフォルダーにあるかを判断することはできませんが、Visual Studio の [定義に移動] または検索ソリューション エクスプローラー ボックスを使用すると、クラス ファイルを見つけることができます。また、これは私の意見ではそれほど大きな問題ではありません。最適化を正当化するファイルを見つけるという問題には、開発時間の 0.1% も費やしません。
名前の衝突
確かに、複数の名前空間を作成すると、プロジェクトに同じ名前の 2 つのクラスを持つことができます。しかし、それは本当に良いことなのでしょうか?おそらくそれを不可能にする方が簡単なのでしょうか?同じ名前の 2 つのクラスを許可すると、90% の確率で物事が特定の方法で機能するのに、突然特殊なケースに遭遇するという、より複雑な状況が生じます。別々の名前空間で定義された 2 つの Rectangle クラスがあるとします。
- クラス Project1.Image.Rectangle
- クラス Project1.Window.Rectangle
ソース ファイルに両方の名前空間を含める必要があるという問題が発生する可能性があります。次に、そのファイル内のあらゆる場所に完全な名前空間を書き出す必要があります。
var rectangle = new Project1.Window.Rectangle();
または、厄介な using ステートメントをいじってみます。
using Rectangle = Project1.Window.Rectangle;
プロジェクト内に名前空間が 1 つしかない場合、さまざまな名前を考え出す必要がありますが、よりわかりやすい名前は次のとおりだと思います。
- クラス Project1.ImageRectangle
- クラス Project1.WindowRectangle
使用方法はどこでも同じなので、ファイルで両方のタイプが使用されている場合に特別なケースに対処する必要はありません。
ステートメントを使用する
using Project1.General;
using Project1.Image;
using Project1.Window;
using Project1.Window.Controls;
using Project1.Shapes;
using Project1.Input;
using Project1.Data;
対
using Project1;
コードを記述するときに常に名前空間を追加する必要がないという容易さ。それは実際にかかる時間ではなく、それを実行しなければならないフローの中断であり、ファイルをたくさんの using ステートメントで埋めるだけです - 何のために?その価値はありますか?
プロジェクトフォルダー構造の変更
フォルダーが名前空間にマップされている場合、プロジェクト フォルダーのパスは各ソース ファイルに事実上ハードコーディングされます。つまり、プロジェクト内のファイルまたはフォルダーの名前変更または移動には、実際のファイルの内容を変更する必要があります。そのフォルダー内のファイルの名前空間宣言と、そのフォルダー内のクラスを参照する他の多数のファイル内の using ステートメントの両方。ツールを使用すれば変更自体は簡単ですが、通常、クラスが変更されていない多数のファイルで構成される大規模なコミットが発生します。
プロジェクト内の単一の名前空間を使用すると、ソース ファイル自体を変更することなく、プロジェクトのフォルダー構造を自由に変更できます。
Visual Studio は、新しいファイルの名前空間を、そのファイルが作成されたプロジェクト フォルダーに自動的にマップします。
残念ですが、名前空間を修正する手間は、名前空間に対処する手間よりも少ないと思います。また、「追加」->「新規」を使用するのではなく、既存のファイルをコピーして貼り付ける習慣が付いています。
インテリセンスとオブジェクトブラウザ
私が考える、大規模なプロジェクトで複数の名前空間を使用する最大の利点は、名前空間階層内のクラスを表示するツールでクラスを表示するときに、追加の構成ができることです。ドキュメントさえも。明らかに、プロジェクト内に名前空間が 1 つだけあると、すべてのクラスがカテゴリに分類されずに 1 つのリストに表示されます。ただし、個人的にはこれがないために困ったり遅れたりしたことはないので、複数の名前空間を正当化するほど大きな利点があるとは思いません。
ただし、大規模なパブリック クラス ライブラリを作成している場合は、 するだろう おそらく、ツールやドキュメントでアセンブリがきれいに見えるように、プロジェクト内で複数の名前空間を使用していると思われます。
.NET の標準は、可能な限りそうするように努めますが、厳格な規則に従うためだけに不必要に深い構造を作成しないことだと思います。私のプロジェクトは、名前空間 == 構造ルールに 100% 従うことはありません。場合によっては、そのようなルールから抜け出した方がクリーン/ベターな場合もあります。
Java では選択の余地がありません。これは理論上うまくいくことと実際にうまくいくことの典型的なケースと言えるでしょう。
@ラセブク:私はこれらのルールに同意しますが、もう 1 つ追加したいことがあります。
クラスをネストした場合でも、それらをファイルごとに 1 つずつ分割します。このような:
// ----- Foo.cs
partial class Foo
{
// Foo implementation here
}
そして
// ----- Foo.Bar.cs
partial class Foo
{
class Bar
{
// Foo.Bar implementation here
}
}
そうだと思います。
まず、名前空間をたどることで、実際のコード ファイルを見つけやすくなります (たとえば、誰かがネイキッド例外コール スタックを電子メールで送信した場合など)。フォルダーと名前空間の同期が失われると、大きなコードベースでファイルを見つけるのが面倒になります。
次に、VS は、親フォルダー構造と同じ名前空間を持つフォルダー内に作成した新しいクラスを生成します。これに反対することにした場合は、新しいファイルを追加するときに毎日実行する配管作業が 1 つ増えるだけです。
もちろん、xis フォルダー/名前空間階層がどの程度深くなるかについては保守的であるべきであることは言うまでもありません。
はい、そうすべきです。そうでなければ混乱を招くだけです。
基準は何ですか?
正式な標準はありませんが、従来、フォルダーから名前空間へのマッピング パターンが最も広く使用されています。
クラスライブラリでは、フォルダーは通常、名前空間構造と一致しますか、それとも混合バッグですか?
はい、ほとんどのクラス ライブラリでは、整理しやすいようにフォルダーが名前空間と一致します。