- ベストアンサー
フォルダー名とクラス名が被らないようにしたい
C#3.5を使用しています。 同じプロジェクト下に「Class1」というフォルダと「Class1」というクラスを 作成してコンパイルすると 「名前空間 'Test' に 'Class1' の定義が既に含まれています。」 というエラーになって、 つまりどちらかの名前を変えれば(例えばClass1のクラス名のほうを「Test_Class1」に変更するなど)問題ないのですが、 できればフォルダの方の名前も、クラスの方の名前も、それぞれの配置位置も変えたくありません。 そういうふうにやるのは不可能なのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> Wizard_Zeroさんはどのように階層を利用しているのでしょうか? まず、クラスを役割や目的で分類します。 次に、分類した複数のクラスを明確に指し示す名称を考えます。この名称が名前空間であり、フォルダ名になります。 例えばこんな感じですね。 MyApp ルート名前空間 Program.cs エントリポイントを含むクラス MyApp.Forms フォームを格納する名前空間 MainForm.cs/SubForm.cs などのフォームクラス MyApp.Forms.Dialogs ダイアログを格納する名前空間 Config.cs/About.cs などのダイアログフォームクラス MyApp.Forms.UserControls ユーザーコントロールを格納する名前空間 MyApp.Storage データの入出力管理を処理する名前空間 File.cs/Chunks.cs などのファイル処理のためのクラス ポイントというか私が気をつけていることは、なるべく.NETに存在する名前を使わないようにしていることと、名前空間の名詞を複数形にすることです。単に「Form」だけだとFormクラスとかち合ってしまうので「Forms」とすることでそれを回避しています。(ビルドができてもインテリセンスが働かなくなってしまうことがあるので) 私の場合はチームや会社で開発した経験がないので、自己流な部分がほとんどですが、名前空間の切り分け方やクラス名の付け方は.NET Frameworkそのものを参考にしました。個人で開発するのであれば、自分流のルールや命名規則を作っておくと良いと思います。(これは名前空間だけでなく変数名やプロパティ名などにもあてはまりますね。)
その他の回答 (3)
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
> MyApp.DataModelsやMyApp.DataDictionariesは何のデータを保持すれば良いのでしょうか? ここはデータの木構造のルートとなる部分なので、各ノードを管理するクラス(例えばコレクションクラス等)や、ノードで共通する部分をカプセル化した基底クラスなどなどですね。 > Expand(ノードが開いているか)だけは保存するデータとした方が良さそう そこはプロジェクトの仕様にあわせればよいと思います。データとインターフェイスを分離するといっても、完全に壁で隔ててしまう必要はありません。
お礼
ご返答ありがとうございます。 大方のイメージができました。 本題からずれた質問かもしれませんが、ここまで回答して頂きありがとうございました。
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
私の場合は、データとインターフェイスはなるべく分けて考えるようにしています。フォームやコントロールは、あくまでデータを可視化し、表示・編集するためのものに過ぎないので、コントロールとデータを直結して構成するとどうしても煩雑になってしまいがちですね。 補足で示した範囲で言うと「データモデル」と「データディクショナリ」という2つのデータのまとまりがあり、それぞれ可視化に適しているのがTreeViewである、と考えられます。「TreeViewを使いたいからデータを木構造にした」のではなく「データの分類法を木構造にしたから、TreeViewを使う」という発想ではないでしょうか? その場合、あくまで主体は「データ」ですので、TreeViewの配下には置かず、データとTreeViewを切り離して考えます。こうすると、データをTreeViewへ送り込む手段が必要になりますが、データのまとまり自体が木構造になっていれば、ノードの構成はさほど面倒ではなくなります。これにはいくつか方法が考えられます。 ・データとTreeViewを受け取ってノードを構成するクラス ・データからノードを構築することができるTreeView継承クラス ダイアログに関しては、補足にあるようにデータの名前空間に埋め込んでしまってもいいですし、Forms.Dialogs名前空間の配下に配置してもいいと思います。正直、ここは悩ましいところですね・・・。 データ構造を完全に把握しているわけでありませんが、私ならこんな感じにします。 [ データ部分 ] MyApp.DataModels MyApp.DataModels.Nodes MyApp.DataDictionaries MyApp.DataDictionaries.Nodes [ インターフェイス部分 ] MyApp.Forms MyApp.Forms.Dialogs MyApp.Forms.Dialogs.DataModels データモデルで使うダイアログ MyApp.Forms.Dialogs.DataDictionaries データディクショナリで使うダイアログ MyApp.Forms.TreeViews データをTreeViewへ送るためのパイプ役になるクラス。 名前空間の切り分けは「何を主体にするか」を意識すると良いと思います。 断片的な情報しか得ていないのでこれを鵜呑みにするのは危険だと思いますが、考え方の参考になればと思います。
お礼
ご返答ありがとうございます。 なるほど、たしかにデータと制御やデザインは分けた方がわかりやすそうですね。 ところでずっとWizard_Zeroさんの[ データ部分 ]の構成を考えていて、 これ以上深く掘り下げるのはどうかと思ったのですが、 どうせ自分で考えても分からなそう(^^;)なので伺いたいのですが、 MyApp.DataModels.NodesやMyApp.DataDictionaries.Nodesの部分は MyApp.DataModels.Nodes ├ メインモデルNodeのデータ集合クラス ├ 外部キーNodeのデータ集合クラス というふうに、それぞれのノード情報に合ったデータのリストを保持してるクラスを記述すれば良いと思うのですが MyApp.DataModelsやMyApp.DataDictionariesは何のデータを保持すれば良いのでしょうか? TreeViewのデザイン部分は[ インターフェイス部分 ]に任せれば良いと思うのですが、 デザインに関することでも、Expand(ノードが開いているか)だけは保存するデータとした方が良さそうですが、 そういうデータなのかなと
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
試してみましたがエラーは出ませんでした。 Class1\Class1.cs 以外にClass1というクラスが定義されていたりしませんか? クラス名ではなく名前空間でかぶっているかもしれません。Test.Class1というクラスとTest.Class1という名前空間は共存できないので別の名前にするしかありません。フォルダ名を変えなくても名前空間を変えることは可能です。 // 定義できない例 // Class1\Class1.cs namespace Tester.Class1 { class Class1 {} } // Class1.cs namespace Tester { class Class1 {} } // これなら大丈夫 // Class1\Class1.cs namespace Tester.Class1A { class Class1 {} } // Class1.cs namespace Tester { class Class1 {} }
お礼
ご返答ありがとうございます。 >クラス名ではなく名前空間でかぶっているかもしれません。 まさにこれでした・・・ Class1フォルダの下に作ったClass2.csファイルに書かれている namespace Test.Class1 { class Class2 { } } の「Test.Class1」が被っていました。 別の名前にするしかないとのことですが、 ここからは別の質問になっちゃうかもしれないので申し訳ないのですが、 やむおえず別の名前にするときに、何かこうコツというかパターンみたいな付け方はあるのでしょうか? 例えばC#での比較的大きな規模のプログラムの場合 Wizard_Zeroさんはどのように階層を利用しているのでしょうか? 自分はできるだけフォルダの階層と名前空間を合わせたいと思ってるのですが。
お礼
ご返答ありがとうございます。 なるほど、複数形を用いるということですね。 具体的でとても参考になりました。 ありがとうございます。 ただもう一つ疑問に思うことがあって、 もしよろしければ最後にもう一つだけお答え頂けないでしょうか? タブで切り替えられる複数のTreeViewをもつアプリケーション(http://paint.s13.dxbeat.com/up/src/paint_19155.jpg.html) の場合、自分としては複数のTreeViewの内容をできるだけ散らばらないように 一つのフォルダの中で記述したいと思い、TreeViewsフォルダを作ってその中にさらに それぞれのTreeViewフォルダを配置して、さらにそれぞれのNodeフォルダを配置する(ここまではやりすぎかなぁ・・・) 次のような構造で考えているのですが、 (文字数の関係で「この回答に補足をつける」を参照して下さい)
補足
TreeViewsフォルダ(このフォルダの中に各TreeViewの内容を配置する) ├─── データモデルフォルダ(データモデルTreeView) │ ├─── メインモデルNodeフォルダ(データモデルTreeViewの中のメインモデルNode) │ │ ├ フォーム(ダイアログ?)(Itemを追加するウィザードみたいな?http://paint.s13.dxbeat.com/up/src/paint_19156.jpg.html) │ │ ├ 設定(メインモデルNodeの共通の設定情報) │ ├─── 外部キーNodeフォルダ │ │ ├ フォーム │ │ ├ 設定 │ ├ フォーム(データモデルTreeViewに共通のフォームデザインや内容) │ ├ 設定(データモデルTreeViewに共通の設定情報) ├─── データディクショナリフォルダ(左から2つ目のタブのTreeView) │ ├─── データディクショナリNodeフォルダ │ │ ├ フォーム │ │ ├ 設定 │ ├ フォーム │ ├ 設定 ├ フォーム(各TreeViewに共通のデザイン&内容でそれぞれが継承します) ├ 設定(各TreeViewに共通の設定情報) これだとWizard_Zeroさんのようなやり方と少し違ってくるような気がするのですが、 例えばWizard_Zeroさんのやり方に当てはめると「ダイアログを格納する名前空間」という風に 分けられているので、 MyApp.Forms.Dialogs フォルダ ├─── TreeViewsフォルダ(ここにTreeViewsフォルダを作ってしまう) │ ├─── データモデルフォルダ │ │ ├─── メインモデルNodeフォルダ │ │ │ ├フォーム(ダイアログ?http://paint.s13.dxbeat.com/up/src/paint_19156.jpg.html) という感じになるのでしょうか? Wizard_Zeroさんならこのアプリケーションの場合、どのように配置を考えますか?