c#特徴の命名の仕方

このQ&Aのポイント
  • c#初心者がライブラリを作る際の命名方法について悩んでいます。コレクションクラスの命名について、構造を名前に付けるか性質を名前に付けるか迷っています。
  • コレクションクラスで、値の取得/設定が高速なクラスと値の追加が高速なクラスの2つを作る予定です。内部の動作が異なるため、どちらかを作らないというのは抵抗があります。
  • 命名方法については、QuickAccessSampleCollectionやQuickAddSampleCollectionのように性質を名前に付けるか、LinkedList<T>やHashTableのように構造を名前に付けるかで迷っています。
回答を見る
  • ベストアンサー

c# 特徴の命名の仕方

 こんにちは、いつものごとく、命名だけで一週間悩むc#初心者です。  現在ライブラリを作っています。  その中にコレクションクラスで、「SampleCollectionBase」という親クラスから、外観は等しく、「値の取得/設定」が高速なクラスと、「値の追加」が高速なクラスの二つをつくり、用途に合わせて使い分ける予定です。  内部の動作がまるっきり異なるので、ことに「追加・挿入」に関しては「List<T>」と「LinkedList<T>」ほどの計算量に差があるので、どちらかを作らないというのはかなり抵抗があります。  それで、命名方法なのですが、名前に性質を付けて、「QuickAccessSampleCollection」、「QuickAddSampleCollection」のような名前にするのがいいか、「LinkedList<T>」や「HashTable」のように構造を名前に付けて、「SampleCollection」、「構造名SampleCollection」のような名前にするのがいいか迷っています。  どなたか分かる方がいらっしゃいましたら教えていただけませんか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

一般的には、ライブラリの名称は、自分だけのためではなく、そのライブラリを他の方が使うことを想定して作るのが普通です。従って、名前に性質を付けて、「QuickAccessSampleCollection」、「QuickAddSampleCollection」のような名前にするのが良いでしょう。 他の方が使用する場合は、通常、内部の構造名を知る必要はありません。それよりも、 そのライブラリを使用することによる恩恵を知りたいのが普通です。つまり、「読込が速いのか追加が速いのか」のほうがより、知りたい情報なのです。

koumei000
質問者

お礼

 回答ありがとうございます。  カプセル化などの観点からいくとやっぱりそうですよね。

関連するQ&A

  • c# でList<T>と似たものを作りたい

    c#初心者です。 c#のList<T>などのコレクションのように動的かつ高速に配列の容量を変更できるクラスを作りたいのですが、Listの構造すら分からないわ、普通の配列で色々やってみて上手くいかないわで困っています。 要はListやDictionaryがもつAddメソッドの基本的な内容が分かれば良いのですが、どなたか教えていただけないでしょうか?

  • キーが2つのHashTable

    いつもお世話になっております。 VB2003でHashTableのような感じでキーを2つつけられるコレクションを探しています。 普通のHashTable(キーが1つ) 社員コード(キー) 名前(値) ---------------------- 000001      あいうえお 000002      かきくけこ 000003      さしすせそ これを… 今回探しているコレクション(キーが2つ) 会社名 社員コード 名前 ------------------------------- 会社A 0000001   あいうえお 会社B 0000001   たちつてと 会社A 0000002   かきくけこ 会社A 0000003   さしすせそ 会社B 0000002   なにぬねの というようにしたいのですが、 このようにキーが2つで値を取り出せるコレクションはあるのでしょうか? それとも自分でコレクションを作らないとダメなのでしょうか? もし作らないといけないようでしたら、参考にソースなど提示していただけるとありがたいです。 よろしくお願いいたします。

  • c言語 ハッシュ表

    下のハッシュ表のプログラムについて質問です.関数enterを二回呼び出して,valueの値を変更して表示させても値が更新されません.値が更新せれるにはどうすればよいのでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASH_SIZE 997 /* ハッシュ表の内部配列のサイズ */ #define HASH_RADIX 97 /* ハッシュ関数用の基数 */ /* ハッシュ表内の連結リストに含まれるノードの構造体 */ struct hash_node { /* ハッシュ表内の連結リストのノード */ char *key; /* キー */ int value; /* キーに対応する値 */ int id; /* キーに付与された通し番号 */ struct hash_node *next; /* 次のノードへのポインタ */ }; typedef struct hash_node HashNode; typedef HashNode *HashNodePtr; /* ハッシュ表の構造体 */ struct hashtable { HashNodePtr *heads; /* 内部配列 */ int serial_id; /* 通し番号管理用の変数 */ int size; /* 内部配列のサイズ */ }; typedef struct hashtable HashTable; typedef HashTable *HashTablePtr; /* 文字列 s のハッシュ値を計算する */ unsigned int hash(char *s) { unsigned int v; v = 0; while (*s != '\0') { v = v * HASH_RADIX + *s; s++; } return v; } /* ハッシュ表を一つ生成し,そのポインタを返す */ HashTablePtr create_hashtable() { HashTablePtr t = NULL; int i; t = malloc(sizeof(HashTable)); t->serial_id = 0; t->size = HASH_SIZE; t->heads = malloc(sizeof(HashNodePtr) * t->size); /* 各連結リストの先頭要素へのポインタは必ず NULL に初期化する */ for (i = 0; i < t->size; i++) { t->heads[i] = NULL; } return t; } /* 指定したポインタ変数に NULL を代入して終わるためのマクロ */ #define delete_hashtable(t) \ (delete_hashtable0(t),t=NULL) /* 実質的な削除作業を行う関数(free 後の NULL 代入は省略)*/ void delete_hashtable0(HashTablePtr t) { HashNodePtr n = NULL, m = NULL; int i; /* 各連結リストの領域を解放 */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { m = n; n = n->next; free(m); } } /* 最後に連結リストの先頭ポインタの領域を解放 */ free(t->heads); free(t); } /* ハッシュ表 t に登録されているキーと値のペアの数を返す */ int get_cardinality(HashTablePtr t) { return t->serial_id; } /* ハッシュ表 t にてキー key に対応する値を調べる */ int lookup(HashTablePtr t, char *key) { HashNodePtr n = NULL; int index; /* ハッシュ表の内部配列の添え字を計算 */ index = hash(key) % t->size; /* index 番目の連結リストを先頭から順に走査 */ n = t->heads[index]; while (n != NULL) { /* 引数で指定された key とハッシュ表内のキーが一致したら 直ちに対応する値を返す */ if (strcmp(key, n->key) == 0) return n->value; /* 走査を次に進める */ n = n->next; } /* ここではキーに対応する値は非負であると仮定し, 見つからなかったら -1 を返す */ return -1; } /* キー key と値 value のペアをハッシュ表 t に登録し,その通し番号を返す */ int enter(HashTablePtr t, char *key, int value) { HashNodePtr n = NULL, m = NULL; int index; index = hash(key) % t->size; /* 内部配列の添え字を計算 */ /* キーが既に存在しているかどうかチェック(lookup() と同じ処理)*/ n = t->heads[index]; while (n != NULL) { if (strcmp(key, n->key) == 0) return n->id; /* 通し番号を返す */ n = n->next; } /* 新しいノードを生成 */ m = malloc(sizeof(HashNode)); m->key = _strdup(key); m->id = t->serial_id; m->value = value; /* 連結リストの add_first() と同様にして連結リストに追加 */ m->next = t->heads[index]; t->heads[index] = m; t->serial_id++; /* 次の通し番号に更新 */ return m->id; /* 登録したキーと値のペアに付与された通し番号を返す */ } /* * ハッシュ表 t に登録されるキーの配列を返す *(この配列のサイズは get_cardinality() で取得可能) */ char **get_keys(HashTablePtr t) { char **keys = NULL; HashNodePtr n = NULL; int i; keys = malloc(sizeof(char *) * t->serial_id); /* 各連結リストを走査し,配列に詰め込む */ for (i = 0; i < t->size; i++) { n = t->heads[i]; while (n != NULL) { keys[n->id] = n->key; /* 通し番号を配列添え字に */ n = n->next; } } return keys; /* 後で free() する必要あり */ } void print_hashtable(HashTablePtr t) { printf("Taro => %d\n", lookup(t, "Taro")); } /* ハッシュ表の使用例 */ int main(void) { HashTablePtr t = NULL; t = create_hashtable(); enter(t, "Taro", 25); print_hashtable(t); enter(t, "Taro", 35); print_hashtable(t); delete_hashtable(t); }

  • c# ポインタ代わりの配列 改定

     こんにちは、c#初心者です。  先ほどの質問に回答がつかなかったので、内容が分かりにくいのだろうと思い改定しました。  汎用ライブラリを作っている途中で、引数にではなく、フィールドにポインタをもてたら良いのになと思う場面が時々あります。  「c#じゃ、クラスがポインタみたいなものだろ!」とおっしゃる方もいるかと思います。  Control c1 = new Control();  Control c2 = c1;  とすれば、確かにc1もc2も同じインスタンスを参照することになりますから、メンバ書き換えても当然もう一方も変わっていることになります。  しかし、問題は互いにスコープ上見えていないクラス同士で同じ値を持ちたい場合、具体的にはあるクラスAのインスタンス内にbとcがあり、bとcで同じ値を参照したい場合です。 class SampleClassA {   SampleClassB b:   SampleClassC c: }  上記のような構造で、b, cともにある方のメンバ変数「value」を持っていたとします。  そして、例えばvalueがクラスのstring型だったとすると、  string text = "テキスト";  b.value = text;  c.value = text;  とすれば同じ値を参照することになります。が、  b.value = "あいうえお"  とすると当然のことながらbのアドレスだけが変更され、cの値は変更されません。これをaの内部で行うのであれば、  b.value = "あいうえお";  c.value = b.value; のようにすればいいわけですが、bやcの中で  value = "あいうえお"; としてしまうと完全にaもcも手も足も出ないわけです。  *value = "あいうえお"; が出来ないわけです。  何とかしようとすると、初心者は3つの方法を思いつきました。 1、イベントやデリゲート 2、SampleClassAに値を置いて、b, cからaを参照できるようにする。 1、ほとんど何でもでき、ある意味完璧ですが、消費メモリが増える上にデリゲートはパフォーマンス上ベストではない(ライブラリなので、別にAPIを作っているわけではないのですが)。 2、「スコープが大変混沌としてよろしくない」と初心者は思いました(多分あっていますよね?)。 3、それで、一度はこんなクラスを作りました。 public class Pointeric<T> {   internal T _cont;   public T Containt   {     get { //略 }     set { //略 }   }   public SampleClass(T val) { //略 } }  これでこのクラスのインスタンスを持っていれば  *b.value = "あいうえお";  の代わりに  b.value._cont = "あいうえお";  ができる。 また当然  c.value._cont  は"あいうえお"になる  しかし、msdnさんのクラス ライブラリ開発のデザイン ガイドラインとやらに「ライブラリはpublicなフィールドを持っちゃダメ」と怒られたのでinternalに。すると同じソリューション(ライブラリ)でもプロジェクトが異なればプロパティを使わざるを得ません。すると速度が全然出ないわけです。  そこで代わりに長さ1の配列をポインタ代わりに使うという手を(最近)思いつきました。  具体的には var _sharedValue = new Pointeric<int>(10); ------------------ _sharedValue.Containt = 5; などとしていたのが、 var _sharedValue = new int[1] { 10 }; ------------------ _sharedValue[0] = 5; という形になります。  気になるのが「この配列はポインタ代わりに使われているんだな」ということにXMLコメントと名前だけで気づいてもらえるかどうかという事です。  まだ経験が浅いので判断しかねます。皆さんのご意見を伺わせてください。また、「こんな方法もあるよ」というのがあればお願いします。

  • C言語で使うことの出来る配列のLIB

    C言語から使うことの出来るSTLのコンテナクラスのようなものはありますでしょうか? 配列の追加、削除、検索、更新を高速で処理したいので(LIST構造)、汎用的に使えるLIBのようなものがあれば教えていただきたいです。

  • 構造体をコレクションに入れて扱いたいのですが…

    当方、Windows2000(SP2) + VB6.0(SP5) の環境です。 今、私が困っている事なのですが、宣言した構造体に入れた値を、 構造体ごとコレクションに追加して扱いたいと言う所なのです。 しかし最初の「構造体をコレクションに追加する」と言う時点で躓いています。 もしかして、構造体ごとコレクションに登録すると言う事は出来ないのでしょうか? 私が考えて書いたコードは以下のようになっております。 --- 標準モジュールにて構造体を宣言 --- Public gcolAddData As New Collection 'Collectionオブジェクト Public Type AddData '各データをレコードで獲得 varName As Variant varPostCd As Variant varAddress As Variant varTellNum As Variant End Type Public gAddData As AddData --- 以下が実際に走っているソースです --- '構造体に取得する With gAddData --- ここで構造体の各変数に値を入れています --- End With '構造体をコレクションに格納 gcolAddData.Add gAddData 普通にAddしてしまう方法なのですが、これでは駄目なのでしょうか。 方法があるのであれば教えて頂けると嬉しいです。 また、これは念の為の確認としてお聞きしたいのですが、 コレクションに追加した構造体を受け取りたい時は 以下のようにSet文で構わないですよね? Dim tmpAddData As gcolAddData Set tmpAddData = gcolAddData.Item(0) 何分、まだこの段階まで進めていない状態ですので……(汗 どうぞよろしくお願いします。

  • どのようなクラス名をつけた方が良いのでしょうか?

    C#でクラスライブラリを自作しようと考えているのですが、 入力された値などをチェックするバリデーションクラスを作りたいと思っています。 プログラム言語「PHP」のフレームワークで 「zend framework」というのがありまして、C#のライブラリでもそのような構造にしたいと思いまして、 そこで次のような構造で ┬ Mylibrary(ライブラリ名) │└ Validateフォルダ │ ├Alpha.css(アルファベットかチェック) │ ├Date.css(日付かチェック) ├Validate.css(各種のバリデーションを繋げて、一括でチェックする、または管理するクラス) というふうに考えていたのですが、コンパイルすると「Validate.css」で次のような 「名前空間 'Mylibrary' に 'Validate' の定義が既に含まれています。」 と名前がバッティングするようなのです・・・ なので仕方なく、「Validate.css」ファイルの方を、 「ValidateManager.css」(←この違いも自分の中では曖昧ですが・・・→)「ValidationManager.css」 や単に 「Validationt.css」 にしたり、それかValidateフォルダ(「namespace Mylibrary.Validate」)の方を 「Validations」(「namespace Mylibrary.Validations」) にしようか迷っています・・・ みなさんなら(このようなライブラリを作るか否かも含めて)どのような名前を付けるのか アドバイスを頂けないでしょうか?

  • C++のstringstreamについて

    こんにちは。 C++のstringstreamについて教えてください。 stringstreamはbasic_stringstream<char, char_traits<char>,allocator<char> >がtypedefされたもので、他にbasic_stringstream<wchar_t, char_traits<wchar_t>,allocator<wchar_t> >というwstringstreamというものも存在していますよね。 同じtemplateクラスに異なるパラメータを渡しているというのはわかるのですが、stringstreamとwstringstreamでは内部実装は異なるものだと思っています。 たとえばwchar_tの場合、文字列に数字などを入れる場合、swprintfという関数を使用しますよね。 同様にcharの場合は、文字列に数字などを入れる場合、sprintfという関数を使用することになるかと思います。 basic_stringstreamクラスはこの関数の切り分けはどのように実現させているのでしょうか? 私は関数のオーバーロード(sprintfとswprintfを同じ名前でラップ)か、クラスの特殊化程度しか思いつきませんでした。 char_traitsが魔法の種のような気がするのですがいまいちよくわかりません。 よろしければご教授願います。 /* 開発環境はVisualStudio2008 academic editionです。 */

  • Collectionクラスへ値を代入するときの型変換

    J2SE 5.0でオートボクシング機能が追加されて云々かんぬん。。。そもそも、Collectionクラスへ値を代入するときには、なぜプリミティブ型からオブジェクト型へ変換しなければならないのでしょうか。データとして合わないから。くらいにしかわかっていません。Javaに詳しい方、宜しくお願い致します。

  • ファイルの保存ダイアログでデフォルト命名したい

    ファイルの保存ダイアログでデフォルト命名したい Win32API(C言語)編 第55章 ファイルを開く・保存のコモンダイアログ http://www.geocities.jp/ky_webid/win32c/055.html をみてファイルの保存ダイアログを出せるようになりました。 しかし、たまーにフリーソフトなどでもファイルを保存する際に、 デフォルトのファイル名が初期値として指定されているものもあります。 私のソフトでもそのようにしたいのですが、色々な部分に文字列を 入れてみて試してみても、思ったとおりの結果にはなりませんでした。 下記は上記サイトに記載されている ファイルを保存する際のダイアログの出し方から引用したものですが、 これをどのようにしたらダイアログが開いた際にファイル名部分に デフォルト命名された状態で開けるのでしょうか? static OPENFILENAME ofn; static TCHAR filename_full[MAX_PATH]; // ファイル名(フルパス)を受け取る領域 static TCHAR filename[MAX_PATH]; // ファイル名を受け取る領域 // 構造体に情報をセット ZeroMemory( &ofn, sizeof(ofn) ); // 最初にゼロクリアしておく ofn.lStructSize = sizeof(ofn); // 構造体のサイズ ofn.hwndOwner = hWnd; // コモンダイアログの親ウィンドウハンドル ofn.lpstrFilter = _T("text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"); // ファイルの種類 ofn.lpstrFile = filename_full; // 選択されたファイル名(フルパス)を受け取る変数のアドレス ofn.lpstrFileTitle = filename; // 選択されたファイル名を受け取る変数のアドレス ofn.nMaxFile = sizeof(filename_full); // lpstrFileに指定した変数のサイズ ofn.nMaxFileTitle = sizeof(filename); // lpstrFileTitleに指定した変数のサイズ ofn.Flags = OFN_OVERWRITEPROMPT; // フラグ指定 ofn.lpstrTitle = _T("名前を付けて保存");// コモンダイアログのキャプション ofn.lpstrDefExt = _T("txt"); // デフォルトのファイルの種類 // 名前を付けて保存コモンダイアログを作成 if( !GetOpenFileName( &ofn ) ) { MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); }

専門家に質問してみよう