こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

c# デリゲート関連の命名について

 こんにちは。c#初心者です。

 今回はデリゲート関連の命名についての質問です。

// ―――――――――――――――――――――――――――――――
// 簡素化のため、フィールド変数のまま書いています

public delegate int SampleDelegate();


public SampleDelegate SampleAction;


public int Value
{
  get { return SampleAction(); }
}

// ―――――――――――――――――――――――――――――――

 上記のようなコードを書いているのですが、「SampleDelegate」に当たる部分、「SampleAction」にあたる部分にはどのような名前をつければいいのかと迷っています。

 SampleDelegateは値を取得するメソッドを表すので「GettingValue」や、「ValueGetter」がいいのか、それとも「ValuePasser」みたいなのがいいのか、それ以外がいいのか、
 SampleActionも「ValueGetter」がいいのかそれとも、メソッドと同じように「GetValue」にするのがいいのかそれ以外がいいのかと悩んでいます。

 最初は「SampleDelegate」が「GettingValue」、「SampleAction」が「ValueGetter」になっているのですが、反対の方がいいような気がしたり、その他いろいろで困っています。

 どなたか詳しい方いらっしゃいましたら教えていただけませんか? できれば「『SampleAction』は動作自体だからGettingValueのように『~すること』 のように動名詞を使い方がいい」のように他の命名においても応用が利く教え方にしていただけるとありがたいです。

投稿日時 - 2012-02-29 01:40:40

QNo.7333606

すぐに回答ほしいです

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

>結局、setとAddは結局同じ動作を含んでいたことに気づいて~
>何もデリゲートを使わなくてもやりたかったことの一部が出来たんです。

はい、そういう事ですね。


>_sampleAction( ←ここまで入れるとツールチップで変数名が表示されるので


或いはカーソルをかざしたりしても出てきますね。
こういうのをひっくるめてインテリセンス(Intellisense)というんですが

VC++2008ではこいつがC#に比べてかなり貧弱なんですよw

ずっと前にVC++で同じようなことしようと試みた事があるんですが、結局その時は
どうあがいても、カーソルをかざすのか、キー入力だったかの、どっちか片方だけしか反映できないという結果だったように思いました。

(まぁ、「貧弱」というのはそれだけの理由では決してありませんが)

次のバージョンでは強化されたと小耳にはさんだので(もうさらにその次が既に触れられるのかな?)幾分期待はしていますが。


・<>について

たぶん見つかりました。
コレっぽい感じではないですか?
http://d.hatena.ne.jp/saiya_moebius/20090129/1233243475

html上でのあれとおんなじみたいですね

&lt;

&gt;

使えば出来るっぽい感じです
List<T>

List&lt;T&gt;

で、リンク先の方はこれだと書いてる側は分かり辛いってんで
{}をかわりに使ってらっしゃる提案をされてますが



それから、<include>使って別ファイルに置き変え出来るっぽいですね

http://msdn.microsoft.com/ja-jp/library/9h8dy30z.aspx


これを使えば、日英別々にxml作っといて、後で簡単に切り替えるといったことが出来るかもしれません。



私のとこでは
dllにビルドしといて
別のC#アセンブリから

参照設定して(xmlファイルも運んどいて)呼び出したら

表示出来ました

自分自身のアセンブリのとこに


/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test"]/*' />


とかをやっただけでは出ず。

うーむ
これが自分のとこでも反応してくれれば最強なんですが
これは出来ないのかな?

投稿日時 - 2012-03-02 01:26:33

お礼

 ありがとうございます。おかげさまで大助かりです。

 インテリセンスってオートコンプリートの事だけかと思っていました。あのツールチップもそうだったのですね。c#に慣れてきてたころに一度VC2010Expressに挑戦してみたのですが、「this->」の時点で意味が分からなくなった上、全然インテリセンスが表示されないのでいったん諦めて、しばらくはc#一本に絞ることにした覚えがあります。

 「<include>」、覚えておきます。

 初心者の長い質問に付き合ってくださって、ありがとうございました。

投稿日時 - 2012-03-02 11:57:15

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(27)

ANo.26

あ、そかそか
<summary>などなどを使えば
C#では解説が出るんでしたねw

VC++2008だとインテリセンスに頼れないことが多々あるので、すっかり忘れていました。

このへんのことは既にOKってことですかね?
http://ufcpp.net/study/csharp/st_comment.html

仮に
言語について一つだけ表示したい場合は

とりあえず開発中は解説が見えなくてもいい!
と割り切れるなら、適当に「かぶりそうにない文字を割り当てといて」

後でそいつらを置換するという方法は思いつきますが…

投稿日時 - 2012-03-01 23:48:40

ANo.25

>VerifiedListについて

そうですね
一個で済むところなら一個ですました方が断然いいです。

また
privateかつreadonlyであるのなら、使用箇所で引数として取るという方法でなくとも、フィールドとして持ってしまっても全体像の可視性は全然よくなってると思います。



>それと後、XMLのコメントのところに「 // 」で区切って日英の両方を書いているのですが、こんな書き方はしないほうが良いのでしょうか?(場合によって<para></para>も使います)


それは分かりません。使う人が「こういう風に使う」という仕様書だけ見れば、あとはコード直接見えなくても使えるぐらいなのが、良質なライブラリと言えるので

別途ドキュメント化してしまう方が一般的かもしれません。

ただ、オープンソースにして誰でも改良を施せるようにするなら
こういう形式でもいいかもしれません。

その場合は、あとは何らかの
テキストエディタ(ソフト)かなんかで、文字の置き換えを簡単に行ってくれるような機能がもしあれば、(無駄ないソースで)日本語用・英語用に別々にリリースするのも可能かもしれません。


>あと、XMLコメントないで「<」の記入に苦労しており、苦しみ紛れに環境依存文字「˂」「˃」で代用していますが、あまり良くないと思います。<xmp></xmp>のようなタグは無いでしょうか? それとも「(in T)」などで代用したほうかよろしいでしょうか?


うーん、コメントに関しては全然詳しくないですw
申し訳ない


私はコメントよりソース主義的なところがあって

人のコードを読む時も

1.まずコメントをほとんど読まずに消す
2.自分の読みやすい文法に書き変えながらついでに挙動を追っていく
3.一通り整形し、目を通して尚且つぱっと見で意味が分かり辛い部分があったら、そこではじめて、消した部分に相当する元のソースのコメントを読んでみる

という手順を、ほとんど踏むのでw

何しろコメントは間違ったこと書いてても、それを修正するの忘れてても
コンパイルエラーにはなりませんからね。


とはいえ、上記のとおり、「オープンソース」かつ「概要説明毎回あり」のケースであれば考えた方が良いかもしれませんが


どういうものをどう書きたいところを
今はその部分が<>含め、どうなっているかっていう具体的なところが分かれば、調べられる、かもしれません。

投稿日時 - 2012-03-01 23:38:04

お礼

 回答ありがとうございます。

 結局、setとAddは結局同じ動作を含んでいたことに気づいて、Clear、Removeは操作ミスで呼び出されるとしたらユーザーだということに気づきました(それ以外は普通、バグって言いますよね)。
 あと、よく考えてみれば何もデリゲートを使わなくてもやりたかったことの一部が出来たんです。

> どういうものをどう書きたいところを今はその部分が<>含め、どうなっているかっていう具体的なところが分かれば、調べられる、かもしれません。
 今回のように自前でデリゲートの型を用意した場合、

_sampleAction( ←ここまで入れるとツールチップで変数名が表示されるので

便利なのですが、その変数にラムダ式を代入する場合に引数の型や名前が思い出せず、しぶしぶどこかで上記のよう入力してにツールチップに頼ったりしていたので、それならいっそのこと

/// <summary>
///   説明
///   <para>>>> void Method(int value, List<T> list)</para></summary>
private Action<T> _sampleAction;

のようにしようと決めたのです…が、なんと、上記の場合「<」がタグ開始として認識されてしまう ということで「˂」「˃」を代用していました(ツールチップ内では「<」「>」より「˂」「˃」の方が違和感が少なかったので使用していますが、「<」「>」でもいいような気がしてきました)。

投稿日時 - 2012-03-02 00:44:47

ANo.24

もうちょい補足です

>>Class1はそれを真似たのですが、よくなかったということですか。

>そいつは状況次第ですね。Class1はあくまでユーザー定義の自由なクラスという仮定ならば、ということですが

ユーザー定義の自由なクラスでなくても、「設定、取得するものは一種類しかない、配列やリストのような働きをするクラス」や「ハッシュっぽいもの」ならば全く問題ないし
むしろ分かりやすいかと思います。

投稿日時 - 2012-03-01 22:10:18

ANo.23

まぁ、ここまでしっかりと受け答えをされていらっしゃる
ということで「初心者」と自称されていますが
仮に自身でそう定義したとしても、客観的には「そんじょそこらの一般的な初心者」とは5枚も6枚も違うと思います。

・分からないことがあったらどんどん聞く、或いは調べる
・自分に分かる範囲で、十分調べている

こういう人は言語に限らず伸びるんですよ。頑張ってください。


で、本題ですが


>Class1はそれを真似たのですが、よくなかったということですか。

そいつは状況次第ですね。Class1はあくまでユーザー定義の自由なクラスという仮定ならば、ということですが


>不正な削除・クリア対策または他のインスタンスとの連携ができないかと

それをチェックするデリゲートを送るとしても
結局監視側はそれを知ってるってことになるでしょうから
その部分でだけ引数で送る、という手ももちろんあります。
(インスタンスを作って渡さないといけないとなると、大規模開発ではその下準備が後で「どうだったっけ」となりやすいので、使用箇所で引数で送った方が、概して分かりやすいという意味です。)



>結局不正な値、インスタンスの追加をまたは、不正な削除を許すことになります。

はい、その「アホ操作」の可能性を全て先読みしてライブラリ側が潰すのは大変な作業ですし、実行時に無駄な処理が発生してしまう恐れも非常に大きいので

「アホ操作」自体が発生しにくいように
「分かりやすい操作」になっている方がいい、っていうのが普通の考え方です。

>例えば、引数「text」が「"word"」という~

これはおそらく、私が最初の方で書いた

>文字列長判定や開始、終了の文字、特定の文字(列)が、ある文字列中に含まれているかの判別については
>Listの管理とは概念的に別なので~



に該当すると思います。



例えば

>var ages = new int[loop] { 5, 4, 3, 2, 1, 0, -1 , 2, 3, 4 };
>// i = 6のとき例外が発生。
>for ( int i = 0; i < loop; i++ )
> sample.Ages.Add(ages[i];
>}


こんな感じの事を、下記LimitableListを使用してやってみましょう。



//ユーザー定義の自由なクラス
internal sealed class MyAgeList {

//今回は要素の上限数使ってないのでList<int>でも別にOK
LimitableList<int> _list;

//ageが利用可能な値かどうか。privateで問題ない。
bool IsAvailableAge(int age_) {
return 0 <= age_ && age_ <= 200;
}

public int this[int i]{
get { return _list[i]; }
set {
if (!IsAvailableAge(value))
throw new ArgumentOutOfRangeException("item");
_list[i] = value;
}
}


public bool Add(int age){
return IsAvailableAge(age) ? _list.Add(age) : false;
}

public MyAgeList(){
_list = new LimitableList<int>();
}

}


込み入った初期化もなく、ものすごく単純ですよね?


↓使ってみる。


MyAgeList agelist = new MyAgeList();
int[] ages = new int[] { 5, 4, 3, 2, 1, 0, -1, 2, 3, 4, 202 };
foreach (int i in ages) {
if ( !agelist.Add(i) ) Text += " " + i;
}


結果(追加できなかった要素を表示する)
-1 202


いかがでしょう?

投稿日時 - 2012-03-01 21:26:14

お礼

 ご意見ありがとうございます。

> こういう人は言語に限らず伸びるんですよ。頑張ってください。
 はい。ありがとうございます。でも、やっぱり独学では井の中の蛙になってしまうのでこの度は本当に感謝しています。

 よくよく考えたのですが、少々凝りすぎていたのかもしれません。そこで間を取って、

/// <summary>
///   値のチェックをサポートしたリストを表します
///   // Represents a list of objects
///   that can check validness of value.</summary>
/// <typeparam name="T">
///   値の型
///   // The type of value</typeparam>
public class VerifiedList<T>
{
  public delegate bool ValidnessCheckCallback(T value);

  // こいつで、追加、割り当て時にチェックする
  private readonly ValidnessCheckCallback _validnessChecker;

  public VerifiedList(ValidnessCheckCallback validnessChecker, …)
  {
  ……
  }
}

 こんなのはいかがでしょうか? 自分なりには改善できたつもりなのですが。

 それと後、XMLのコメントのところに「 // 」で区切って日英の両方を書いているのですが、こんな書き方はしないほうが良いのでしょうか?(場合によって<para></para>も使います)
 あと、XMLコメントないで「<」の記入に苦労しており、苦しみ紛れに環境依存文字「˂」「˃」で代用していますが、あまり良くないと思います。<xmp></xmp>のようなタグは無いでしょうか? それとも「(in T)」などで代用したほうかよろしいでしょうか?

投稿日時 - 2012-03-01 22:57:08

ANo.22

文字列長判定や開始、終了の文字、特定の文字(列)が、ある文字列中に含まれているかの判別については
Listの管理とは概念的に別なので

Listサイドに突っ込まれてない形になってる方が分かりやすいです。
(Listから取り出した文字列を使って、Listの外で判定する)

ここもまた、オブジェクト指向の考え方です。


「Listの要素に」含まれているかどうかの判別は

List<T>を継承してればExistsで簡単にできると思いますが

もっと簡単にするならこういう事も考えられます
↓(制限可能、という意味でLimitableに変え、さらに0のときの仕様を変えました)


public class LimitableList<T>: List<T> {

//さっきのは実際には「0より大きい時」でしたが、今回はほんとに0以上を指定すると上限を設定

public int Limit { get; set; }
public new bool Add(T t) {
if (0 <= Limit && Limit <= Count) return false;
base.Add(t);
return true;
}

public void Unlimit(){ Limit = -1; }
public bool Exist(T t){ return Exists(a => { return a.Equals(t); }); }

public LimitableList(int limit) { Limit = limit; }
public LimitableList() : this(-1) { }

}



実験

using NameOfLibrary;






LimitableList<string> list = new LimitableList<string>(0);

Text += " " + list.Add("追加0"); //この時点では追加されない

list.Unlimit();

Text += " " + list.Add("追加1");
Text += " " + list.Add("last");
Text += " " + (list.Exist("last") ? "exists" : "not exist");
Text += " " + (list.Exist("追加0") ? "exists" : "not exist");


結果
False
True
True
exists
not exist

投稿日時 - 2012-03-01 17:51:58

お礼

 ご指摘ありがとうございます

「TreeListView」は「TreeView」の間違いでした。

> Get~というメソッドを「~」の部分を変えて2つ作るほうが、普通な可能性があります。
 TreeViewに「public ControlCollection Controls」や、「public TreeNodeCollection Nodes」などがあり、それぞれのコレクションにインデクサ、Add、RemoveメソッドがあったのでClass1はそれを真似たのですが、よくなかったということですか。

> ほとんどprivateやprotectedで作っています。(なので使う側としてはごちゃごちゃしてません)
 CListは基本的に他のライブラリ内のクラスのパーツになります(その際ごく一部は派生して使用)。使う側は基本的にインデクサと、Add系とRemove系とClearだけです。

> ということであれば、先ほどの私のLimitListをprivateフィールドにもった
もうちょっと具体的なクラスをまた作ればいい
 不正な削除・クリア対策または他のインスタンスとの連携ができないかと

> (Listから取り出した文字列を使って、Listの外で判定する) 
 この方法は最初に思いつきましたが、結局不正な値、インスタンスの追加をまたは、不正な削除を許すことになります。

> 「Listの要素に」含まれているかどうかの判別は
 勘違いを引き起こさせてしまったようです。例えば、引数「text」が「"word"」という文字列を含んでいるかどうかと言う意味です。含んでいなければ例えば文法エラー扱いにするなど。

 よく考えてみれば名前が微妙だったかもしれません。「~List」より「WatchedCollection」、「~Collection」のほうが良かったのかもしれません。

投稿日時 - 2012-03-01 20:47:33

ANo.21

> LimListを例えばClass1内部で宣言し、取得専用publicプロパティ「public LimList<int> Ages { get; set; }」として使ったとします。その際、外部、例えばClass2から「Ages.Limit」を勝手にいじられたのではいくらClass1で制限を調整しようと思っても無理です。


その前提は、そもそも「オブジェクト指向的には非常事態」です。

そういうときは普通はLimList<int>をpublicにアクセスできるようにしたりしません。

Class1がどういうクラスであれ、例えば
そいつに対して
Add何々(~);
というメソッド「だけ」を公開し

そのAddの内部で_agesとかへの追加処理を施す、といった形にします。

>LimListを2つ以上使うような場合では無理ですし、何を取得するのかが明確でない場合も多いと思います。

そういうときはClass1に
Get~というメソッドを「~」の部分を変えて2つ作るほうが、普通な可能性があります。


TreeListViewのNodesプロパティがあるとしたら
こいつをpublicにするかどうかはまた別問題です。

私がC++で作ったものは、最終的に操作名が分かるstaticな関数名以外
ほとんどprivateやprotectedで作っています。(なので使う側としてはごちゃごちゃしてません)

>宣言場所のみ、または許可された範囲内でのみ制限や処理をいじれるようにするため

ということであれば、先ほどの私のLimitListをprivateフィールドにもった
もうちょっと具体的なクラスをまた作ればいい、あるいはもしLimitがreadonlyに出来るならそれで十分、というだけです。

投稿日時 - 2012-03-01 16:53:36

ANo.20

編集途中でした。
LimitedList→LimitListに直してください。

投稿日時 - 2012-03-01 15:32:09

ANo.19

そういうことであれば、もっともっとシンプルにするべきだと思います。
CList(Controled)と言われても、聞くまでControledの意図が正確に分かんなかったのと、Controledという意図を読み取ることを、聞くまで半ば放棄してしまいかねないこと…(ClassなのかControlなのか、その他なのか)

なにしろ、C++だとCListという名前のものがMFCというライブラリにあるなどなどから

CListという名前から「そういう意図が読み取れる」という事は期待しない方が良いように思います。

この場合名前から読み取らなくても使えるくらい簡潔になっているべきと思います。


また、現状ではCListActionBox<int>やCList<int>の制御コードを、使う側がいちいち書かないといけないということになりますが

こういったことは汎用ライブラリらしくありません。
CList<int>とCListActionBox<int>の関係性を理解してないといけないというのもきついとこです

こういう意図なら
少なくともデフォルトでは、CListがそれをユーザーに変わって自動で行うような機構にするのが自然です。


このコードだと現状LimitList、かSafeListぐらいの意味合いにして
そう言うListにしてしまった方が分かりやすいと思います。


Listに機能追加するという事なら
細かいとこは省きますが

using System.Collections.Generic;

[assembly: CLSCompliantAttribute(true)]

namespace NameOfLibrary {

public class LimitedList<T>: List<T> {

public int Limit { get; set; } //0以上を指定すると上限を設定
public new bool Add(T t) {
if (0 < Limit && Limit <= Count) return false;
base.Add(t);
return true;
}

public LimitedList(int limit) { Limit = limit; }
public LimitedList() : this(0) {}

}

}

この程度でも、意味的にはそこそこ行ける(ちゃんとやるならListの機能をしっかり把握しきるか、それに依存しないように自分で0から書かないといけませんが)

と思います。



色々実験↓

NameOfLibrary.LimitList<string> list = new NameOfLibrary.LimitList<string>();

Text = "";
Text += " " + list.Add("a");
Text += " " + list.Add("list[1]");
Text += " " + list.Add("last");

try {
list[0] = "Nice to meet you.";
list[3] = "3333";
} catch (ArgumentOutOfRangeException e) {
Text += " " + e.Message;
}

Text += " " + list.Count;
list.ForEach(s => { Text += " " + s; });



結果(実際は改行ではないですが、分かりにくいので改行します)
True
True
True
インデックスが…(ArgumentOutOfRangeException例外)
Nice to meet you.
list[1]
last

投稿日時 - 2012-03-01 15:19:02

補足

下記のstringに対応する云々は、お分かりかと思いますが文字列長だけではなく開始、終了の文字の判別、含まれているかどうかなどの判別も行います。

投稿日時 - 2012-03-01 16:30:23

お礼

 ご指摘ありがとうございます。

 実はLimList<T>(Limited List)は製作済みです。ただし、これはIComparable<T>を実装したものしか対応しておりません。そこで文字列であろうと、Collorであろうと対応できるもので、なおかつ特定の値や動作に対して反応し、カウントするなどの機能をもたせるためのものでもあります。

 さらに、~ActionBoxを作ったのは訳があります。
 
 LimListを例えばClass1内部で宣言し、取得専用publicプロパティ「public LimList<int> Ages { get; set; }」として使ったとします。その際、外部、例えばClass2から「Ages.Limit」を勝手にいじられたのではいくらClass1で制限を調整しようと思っても無理です。
 Class1で「public int this[int index] { get; set; }」のようにする手も有りますが、LimListを2つ以上使うような場合では無理ですし、何を取得するのかが明確でない場合も多いと思います。実際、例えば「TreeListView」は「Nodes」プロパティを持っています(飽くまで例です)。
 そのためLimListもCListも本体と制限値、処理を半ば切り離すような形でLimBox<T>、CListActionBox<T>を用意したにいたります。

 宣言場所のみ、または許可された範囲内でのみ制限や処理をいじれるようにするためにとった苦肉の策です。結果として、いわば「public」のような「internal」になったかと思います。

投稿日時 - 2012-03-01 16:11:36

ANo.18

(ん~まぁ、仮に最善の構造になってるとして)

ここまでの情報からだと「単に変形させる」だけとすれば
こういう書き方も可能ではないかと思うのですが
こういうのだとダメな理由はありますか?


using System;

namespace Controled {

//エラーチェックはどのタイミングでどう行われるべきか現状分からないので省略します。
public class ActionBox<GETTER, SETTER> {
public GETTER ItemGetter { get; set; }
public SETTER ItemSetter { get; set; }
}

public class List<T> {

//Func<int, T>やAction<int, T>のかわりにデリゲートを使っても良いでしょうが

readonly ActionBox<Func<int, T>, Action<int, T>> _actionBox;

public int Num { get; set; } //実験用
public T Data { get; set; } //実験用

public T this[int i] {
get { return _actionBox.ItemGetter(i); }
set { _actionBox.ItemSetter(i, value); }
}

public void Action1(int num, T data){ Num = num; Data = data; } //実験用

public Func<int, T> GetFunc { set { _actionBox.ItemGetter = value; } }
public Action<int, T> SetFunc { set { _actionBox.ItemSetter = value; } }
public List(){
_actionBox = new ActionBox<Func<int, T>, Action<int, T>>();
SetFunc = Action1;
}

}

}




フォームアプリのFormのコンストラクタで試す。


Controled.List<int> items = new Controled.List<int>();

items.GetFunc = (int x) => { return x + 10; };
items[10] = 100;
Text = items[10] + " " + items.Num + " " + items.Data;


結果
20 10 100


関数とデータは近くに置いてないと無駄に分かりにくくなってしまったりするので
(オブジェクト指向に反する)

継承と仮想関数で解決できるんならそれに越したことはないんですが


また、「インデクサを使うからには」連想配列的(ハッシュ)的な動きをするとか、そのオブジェクトが配列操作メインの物である
ような形じゃないと無駄に分かりにくくなってしまったりすると思います。(上記実験では実際の用途が分からなかったので、最終的なフォームの呼び出し側だけみても分かりにくいコードになっています)

投稿日時 - 2012-03-01 06:06:14

お礼

 ご指摘ありがとうございます。

 このような構造にした意図が伝わりづらかったと思うのでまとめさせてもらいます。

・まず、CList<T>の働きは、既存のList<T>の機能に加え、値のチェックを行う機能をつけたもの。
・CListActionBox<T>は基本的にCList<T>と同じ場所でフィールド変数として宣言され、そのクラス内のコンストラクタ内でCListの初期化時にCListActionBoxが引数として渡される。
・既存の「Action」、「Fanc」を用いなかったのは引数の内容を分かりやすくするため(ライブラリなので丁寧目に)。

public class SampleClass
{
private CListActionBox<int> _ageActinons;

private CList<int> _ages;

public CList<int> Ages
{ get { return _ages; } }

// - - - - - - - - - - - - -

private CListActionBox<string> _messageActions;

private CList<string> _messages;

public CList<string> Messages
{ get { return _messages; } }

// - - - - - - - - - - - - -

public SampleClass()
{
  // ↓のとき、_ageActionsの読み取り専用フィールド
  // DefaultItemGetter、DefaultItemSetter
  // DefaultItemAdder、DefaultItemRemoverに
  // (index) => { return _bodyArray[index]; }
  // (index, value) => { _bodyArray[index] = value; }
  // Add(T item)の根幹部分
  // Remove(T item)の根幹部分
  // が代入されます。
  _ages = new CList<int>(out _ageActions);
  _ageActions.ItemGetter = DefaultItemGetter;
  _ageActions.ItemSetter = (index, age) =>
  {
    if ( age < 0 || 200 < age )
      throw new ArgumentOutOfRangeException("item");
    _ageActions.DefaultItemSetter(index, age);
  }
  _ageActions.ItemAdder = (age) =>
  {
    if ( item < 0 || 200 < age )
      throw new ArgumentOutOfRangeException("item");
    _ageActions.DefaultItemAdder(age);
  }
  _ageActions.ItemRemover = _ageActions.DefaultItemRemover;

  ………
}

// --------------------------------------------------

// 使用例
public void Main(string[] args)
{
int loop = 10;

var sample = new SampleClass();
var ages = new int[loop] { 5, 4, 3, 2, 1, 0, -1 , 2, 3, 4 };

// i = 6のとき例外が発生。
for ( int i = 0; i < loop; i++ )
  sample.Ages.Add(ages[i];
}

// ----------------------------------------------

のような感じです。CList<T>内部の挙動を監視するための動作をSampleClassの内部で設定しています。

投稿日時 - 2012-03-01 08:01:16

ANo.17

なるほど。

つまり
CListActionBox<T>
は派生しない使い方が基本的ってことでしょうか?

う~ん

コードを見て冷静に考えれば考えるほど
実際にどういう状況でこれらのクラスを使いたいのかが分からなくなってきました。
仮想関数では出来ないぐらいに自由な

イベントハンドラの任意関数版
を作りたいって感じでしょうか?

投稿日時 - 2012-03-01 03:01:18

お礼

 解答ありがとうございます

> 派生しない使い方が基本的ってことでしょうか?
 確かに基本的にはそうですが、派生します。具体的には自作コントロール内で各データ郡をより効率的に管理できる機能を持たせたものに派生します。

投稿日時 - 2012-03-01 13:50:17

ANo.16

すみません

public ItemGettingCallback ItemGetter {
get { return _itemGetter; }
protected set { ItemGetter = value; }
}



public ItemGettingCallback ItemGetter {
get { return _itemGetter; }
protected set { _itemGetter = value; }
}

です。

投稿日時 - 2012-03-01 01:48:35

ANo.15

>現在リファクタリングですが、なにせ多岐にわたって「protectedフィールド」を作ってしまったものですから根幹部分のクラスから修正中で、CList系には手を付けられていません。
>今回のものに関してはつい癖で「protected」としてしまっただけで、継承先ではまだ使用していません。
>可能性が十分にあるものとしています。


なるほど、そう言う状況ですか

命名を考えるにあたっては
十分に構造を把握しないといけないので
(不要なメンバがある場合は前提が変わってくるなど)
もうちょい確認させてください。


では、まず単純にこれらのフィールドをprivateにして置き

private ItemGettingCallback _itemGetter;
public ItemGettingCallback ItemGetter { get; set; }

このパターンがもしベストなのであれば

この_itemGetterが変更されるというのは
ItemGetterのsetで行われることとする

という風になると思われますが
もしこの部分が継承先からしか変更されないとかなら、

public ItemGettingCallback ItemGetter {
get { return _itemGetter; }
protected set { ItemGetter = value; }
}

こんな風にもできますね(アクセス修飾子は可能な限り強力なものを優先できる構造にすると、後で修正や拡張が楽です。)

もう少し

このItemGettingCallback
などのデリゲートですが
これが「見えないといけない範囲」ってpublicじゃないといけませんか?


これらのコードから類推すると

最終的に、外部からはT(ジェネリック)1個だけ指定すればOKそうな気もしなくもないんですが

投稿日時 - 2012-03-01 01:46:34

お礼

 解答ありがとうございます。

> これが「見えないといけない範囲」ってpublicじゃないといけませんか?
 CListActionBox<T>はその名前の通り本当に単なる入れ物でそのクラス内でnull対策などの適正化以外の処理は行われません。
 使い方は

// -------------------------------------------------

private CListActionBox<int> _itemActions;

public CList<int> SampleItems
{ get { return _sampleItems; } }

// -------------------------------------------------

などのようにして、クラス外部からでも、そのインスタンスを定義した場所と密接にかかわる部分で「CList」の「get」「set」を初めとする処理の変更を可能にするものです。そのため「protected set」にはできないと思います。

> このItemGettingCallbackなどのデリゲートですがこれが「見えないといけない範囲」ってpublicじゃないといけませんか?
 上記のように用いるため「public」にしないとアクセシビリティのエラーが発生します。

投稿日時 - 2012-03-01 02:34:30

ANo.14

あー、意味分かんない箇所がw
正しくは


CListActionBox<T>クラスか派生クラス
CList<T>クラスの派生クラス



CListActionBox<T>クラスの派生クラスか
CList<T>クラスの派生クラス

ですw

投稿日時 - 2012-03-01 01:25:24

ANo.13

むむ?

CListActionBox<T>クラスの
protected ItemGettingCallback _itemGetter;
protected ItemSettingCallback _itemSetter;


public class CList<T>クラスの
protected readonly CListActionBox _actionBox;

はフィールドですよね。

public ItemGettingCallback ItemGetter { get; set; }
↑こういうのがプロパティ

フィールドがprotectedな場合は、下記の通り「_」ではじめるとCLS準拠じゃない
及び
#7の

>パブリック フィールドとプロテクト フィールドは適切にバージョン管理されず

に引っかかってしまう恐れがあるので
こいつらはprivateにしないとまずいかもしれません。

protectedでないといけない理由があるとしたらそれは「確実に派生クラスのコードに存在する」と思うので、

CListActionBox<T>クラスか派生クラス
CList<T>クラスの派生クラス

を、一つでも見せていただくことは可能ですか?(_itemGetterや_itemSetterや_actionBoxを使っている部分で良いです)

また
_itemGetter;
_itemSetter;
はreadonlyではないですが

これは変更可能性がありますか?

投稿日時 - 2012-03-01 01:16:37

お礼

> パブリック フィールドとプロテクト フィールドは適切にバージョン管理されずに引っかかってしまう恐れがあるのでこいつらはprivateにしないとまずいかもしれません。
 現在リファクタリングですが、なにせ多岐にわたって「protectedフィールド」を作ってしまったものですから根幹部分のクラスから修正中で、CList系には手を付けられていません。

> protectedでないといけない理由があるとしたらそれは「確実に派生クラスのコードに存在する」と思うので、
 今回のものに関してはつい癖で「protected」としてしまっただけで、継承先ではまだ使用していません。

> これは変更可能性がありますか?
 可能性が十分にあるものとしています。

投稿日時 - 2012-03-01 01:28:48

ANo.12

ここでいうCLSはCommon Language Specificationのことですね

ここに概要が集約されてるように思います。

言語間の相互運用性
http://msdn.microsoft.com/ja-jp/library/730f1wy3%28v=vs.80%29.aspx


>どのようなプログラミング言語を使用しているコードからでも確実に利用できるマネージ コードを作成できるように、共通言語仕様 (CLS: Common Language Specification) と呼ばれる、各種の言語を利用する場合に必要とされる言語機能や規則のセットが定義されています。


つまり、Visual BasicからだろうがC#からだろうがC++/CLIからだろうが
その他の、マネージコードをサポートする言語だろうが

CLS準拠になっていれば
正式にサポートされてる、どの言語からでも使えるようなマネージコードのdllになる、ということです。(もしかしたら実際のところは不完全かもしれませんが、概念的には少なくともそう書いてあります)


koumei000さんの過去質問をいくらか拝見させていただきましたが
パフォーマンスを気にしてらっしゃる回もありましたね。

パフォーマンスを本当に求めたいなら
現状では、やはりネイティブなCやC++がだいぶ勝る場合が多いです。

で、C#からネイティブC++のdllを呼び出すとかも、可能は可能ですが、色々と不自由が付きまといます。
そこで、C++/CLIを橋渡しとして使う、といった手法があったりします。


C#側がメインでそこからC++/CLIを少し使う、といったことは現状でもできるでしょうが

もし今作ってるC#のクラスライブラリがCLS準拠になってれば
C++/CLIをメインにして、そっからC#のライブラリを安心して使う
という手もその時自由に選択できるようになる、ということのはずです。


>ということは継承先で触る必要性のあるものに関しては「protected」プロパティにすれば良いということでしょうか?


はい、それで良いはずです。




・コードについて

とりあえず、ここまで書いて投稿しようとして

その前に
別タブで確認して、お礼いただいたことに気付いたのですが
上記の内容が伝わるのは早い方が良いと思うので
この回答は先に載せておきます


内容は今から確認しようと思うので
ちょっと待ってくださいね。

投稿日時 - 2012-03-01 00:58:30

お礼

 早速の解答ありがとうございます。

> どのようなプログラミング言語を使用しているコードからでも確実に利用できるマネージ コードを作成できるように、共通言語仕様 (CLS: Common Language Specification) と呼ばれる、各種の言語を利用する場合に必要とされる言語機能や規則のセットが定義されています。
 お恥ずかしいことにCLSをプログラミング言語の一種と勘違いしていました。勉強になります。

> パフォーマンスを本当に求めたいなら
 確かにパフォーマンスは求めていますが、とりあえず、C++よりC#の方が簡単なので多言語への挑戦はC#でそこそこなってからにしておきます。

投稿日時 - 2012-03-01 01:13:31

ANo.11

>Yune-Kichiさん

確かに見返してみると
今回の要件では、あるいはCLS準拠の必要はないかもしれませんが
このクラスライブラリがもし多言語から使われるなどなどといったことが今後想定される得るのであれば

準拠しておけるなら準拠しておいた方が確実、ですよね。

>CLS違反であるuintなどを使ってもprivateであればCLSCompliant(true)なクラスだったりします。

内部的に関数切り分けして、その部分は外には公開しないとかなら
そこだけinternalにすればprivateまでいかなくてもOKですし

(ていうか、CLS 準拠が関係する部分じゃないなら、もともとメソッドや型の命名規則とかもそんなに拘らなくてもいいんじゃないかなと。)


CLS 準拠コードの記述
http://msdn.microsoft.com/ja-jp/library/bhc3fa7f%28v=vs.80%29.aspx


それ以外については、やはりそうですね。


ここまでの内容を含めて、尚且つもう一歩進んだ命名法を考える
というためには、とりあえずは

現状の継承構造とか、デリゲートになってる
_sampleBox.SampleAction();
とか
SampleBox
とかの内容を見てみたいですね。

投稿日時 - 2012-02-29 20:34:14

お礼

 ご意見ありがとうございます。

 思い返してみれば、継承時の高速化に拘りすぎて、あちこち「protected」だらけでむしろ「private」なんて構造体以外では見かけない状態でした。

>SampleBoxとかの内容を見てみたいですね。

 とりあえず現段階での状態はこんな感じです。

// ----------------------------------------------

// これが「SampleBox」
// <summary>
//   Cは「Controled」の略。…</summary>
public class CListActionBox<T>
{

// 実はこれが例の「SampleDelegate」。戻り値はTで、引数あり
public delegate T ItemGettingCallback(int index);

// ↓の二つが「SampleAction」
protected ItemGettingCallback _itemGetter;

// 省略。setアクセサでは「value」が「null」時に既定動作の代入あり
public ItemGettingCallback ItemGetter { get; set; }


// set用もあったりする
public delegate void ItemSettingCallback(int index, T item);

protected ItemSettingCallback _itemSetter;

// 省略。setアクセサでは「value」が「null」時の既定動作の代入あり
public ItemSettingCallback ItemSetter { get; set; }


// コンストラクタは省略
}

// - - - - - - - - - - - - - - - - - - - - - - - - -

/// <summary>
///   Cは「Controled」の略。…</summary>
public class CList<T>
{

protected readonly CListActionBox _actionBox;

// ここが「public int Value」だった部分
public T this[int index]
{
get { return _actionBox.ItemGetter(index); }
set { _actionBox.ItemSetter(index, value); }
}


// コンストラクタに「CListActionBox」の引数あり
// その他は省略
}

// ----------------------------------------------

 こんな感じで至る所に「protectedフィールド」があります(省略した部分にも山ほど)。また、「CList<T>」は

public CList<int> SampleItems
{ get { return _sampleItems; } }

 こんな感じで1クラスに複数使う予定です。

 速度は計算量の問題なのは分かっていますが、一度プロパティとフィールド変数の速度の差を測定してしまってから至る所に「protectedフィールド」を使うようになってしまいました。

 これらは「protectedプロパティ」に置き換えれば片付く問題なのでしょうか?

投稿日時 - 2012-03-01 00:54:45

ANo.10

MSのデバッグ用のリファレンスコードでも,_から始まるフィールドは使われています。
Reflectorで誤ってSystem.dllを見てしまったことがありますが,_から始まるフィールドがありました。
privateフィールドに関しては,_から始めて問題ないと思います。
元々,_から始まる識別子はC#に関してそれ自体は文法違反等ではないです。
CLSは別物ですし,CLS違反であるuintなどを使ってもprivateであればCLSCompliant(true)なクラスだったりします。


protectedフィールドに関しては,「それを定義したクラスが与り知らぬ場所で変更される」という点で,publicフィールドやグローバル変数と同じ問題があります。
それ故に,protectedフィールドは勧められません。
# MSDNの書き方はどうかと思いますが……
また,その理由から,constやreadonlyの修飾のなされたprotectedフィールドであれば同様のpublicフィールドと同じく,使用しても問題ないと思います。

投稿日時 - 2012-02-29 19:41:50

お礼

 解答ありがとうございます。

 CLSってコマンドプロンプトの類ですよね?(間違っていたらすみません)たしかに、大文字と小文字の区別が無かったと思います。CLSに使うかどうか不明ですが、今後の役に立つと思います。

> protectedフィールドに関しては,「それを定義したクラスが与り知らぬ場所で変更される」という点で,publicフィールドやグローバル変数と同じ問題があります。それ故に,protectedフィールドは勧められません。

 ということは継承先で触る必要性のあるものに関しては「protected」プロパティにすれば良いということでしょうか?

投稿日時 - 2012-03-01 00:19:34

ANo.9

あ、これかな
http://msdn.microsoft.com/ja-jp/library/x8ak87y5.aspx

C#なら、フィールドの名前について
private以外だとダメで
privateならOK、っぽいですね。

どの道privateにしなきゃいけないってことなので、それを守る限りにおいて問題はない、が正解のようですね。

投稿日時 - 2012-02-29 18:55:52

お礼

 やっぱりprivateにしなければならないのですね。いろいろと勉強になりました。ありがとうございます。

投稿日時 - 2012-03-01 00:14:28

ANo.8

一応確認してみました(C++)

namespace だ、だめですよぅ{
struct AAAA { int _inline; };
int BBBB(int _fastcall){ return _fastcall; }
}

う~んw

これに関しては、VC++2008で両方ダメでした。namespaceなくしてCでコンパイルしても通らない…
まぁこれらは、青色になっちゃいますし、明らかに「こんなん書こうと思うなんて」あり得ないとはおもいますがw

まぁでも、サンプルも結構あることだし
C#のprivateなフィールドで
「_+小文字スタート」は、「大抵は大丈夫」なのかなぁ

投稿日時 - 2012-02-29 18:28:12

お礼

 わざわざ確認してくださってありがとうございます。C++に移行する際の参考にさせてもらいます。

投稿日時 - 2012-03-01 00:11:04

ANo.7

>「__」および「_+大文字」で始まる識別子は~たぶんこの辺は C# でも同じなんじゃないでしょうか.

あ~!
なるほど、正確にはそういう風になっていたのですか。
それは大変失礼しました。

C++だと、連続して使うならちょー短い名前のローカルのポインタconst変数に移し替えることが多かったので「ぜってー使わん!」でも全然OKだったのですが。

C#だったらフィールドに前置き「_」使うとよさそうですね。



> 残念ながら、その、ライブラリを作っているのです。

なるほど、そういう御用件でしたか


>パブリック フィールドとプロテクト フィールドは適切にバージョン管理されず、またコード アクセス セキュリティ要求によって保護されません。 パブリックに参照可能なフィールドを使用する代わりにプライベート フィールドを使用し、それをプロパティを通じて公開してください。 


そのまんまだと思います。
内部的に適切にバージョン管理されないようになってしまうので(どうしてそうなるかはMSしか知らないブラックボックスでも、問題ない)

公開するクラスライブラリのフィールドは
全部privateにしとけ、ということでしょう



これは基本的なことですが

「局在性の高いもの」ほど
短い名前で済みやすいというのが挙げられます。

publicよりprotectedが、protectedよりprivateが
メンバよりローカル変数のが

作用する相手は少なくて済むので、より短い名前で十分、というのはC、C++、C#すべて共通で言えると思います。

ローカル変数なんて、その関数内で使う数が少ないなど「実装者が十分バグフィックス楽なら」小文字1つでもOKなこともあります。

投稿日時 - 2012-02-29 17:29:20

お礼

 なるほど。勉強になりました。ありがとうございます。これから修正していきます。

投稿日時 - 2012-03-01 00:10:13

ANo.6

すみません, C# と関係ないところで 1点突っ込ませてください>#3.

「__」および「_+大文字」で始まる識別子は完全に処理系予約ですが, 「_」で始まるその他の識別子は
・C なら「ファイルスコープ」で予約
・C++ なら「グローバル名前空間」 (と ::std 名前空間) で予約
です. つまり, どちらにおいても構造体メンバや関数にローカルな変数 (引数を含む) 名には利用可能です. たぶんこの辺は C# でも同じなんじゃないでしょうか.

もっとも, 「ふつ~の識別子」を使っても規格が変わったらアウトだったりしますが.

戻って, と.

あ, 「delegate には命名規則がある」ということは, 逆に言えば
Func<ほにゃらら> なんかを使えば「自由な名前にできる」
かも. ただ, そうするとやっぱり「使う場面」を想定しておく必要があるんじゃないかな. もちろん delegate (相当) なので「使う場面」には
・その delegate (相当) を取り出す場面
・取り出した delegate (相当) を使ってメソッドなりなんなりを呼び出す場面
の両方を考えないといけないんでしょうね.

投稿日時 - 2012-02-29 16:57:01

ANo.5

Func<int>

delegate int デリゲート名();

とおんなじことですよ。
Actionは戻り値voidですが
Funcの場合、<>内が一個なら
Func<戻り値>で
二個以上だと

Func<引数1, 引数2, 戻り値>

等のようになります。



>実は、この「private」級のフィールド変数の命名には苦心しています。

もし大量に既に作ってしまっているなら
その部分については一端そのままでもいい、かもしれません。
(将来バージョンアップでコンパイルエラーが出たらそこだけ直す、など)


「これ以上ないシンプルかつ分かりやすい名前」というのは、その場の全体の構造の影響をうけますから

何がどうなってるのかが見せていただくことが出来れば
(オブジェクト指向的な構造化というのはC++でもC#でも十分通じるところがあると思うので)

もうちょい方法を考えれる、かもしれません。

投稿日時 - 2012-02-29 15:58:54

お礼

 ご指摘ありがとうございます。
> なので、koumei000さんがライブラリ作成時の話をされているのならこの通りでしょうが
 残念ながら、その、ライブラリを作っているのです。
 先ほどフィールドのデザインを見たのですが、それによると「protected」なフィールドはダメと在るのですが、具体的にはどうダメなのでしょうか?
(パブリック フィールドとプロテクト フィールドは適切にバージョン管理されず、またコード アクセス セキュリティ要求によって保護されません。 パブリックに参照可能なフィールドを使用する代わりにプライベート フィールドを使用し、それをプロパティを通じて公開してください。 → ???)


> Func<int>はdelegate int デリゲート名();とおんなじことですよ。

 お恥ずかしいことに
 「delegate void Fanc<TResult>(out TResult result)」
 と見間違えていたようです。


 また、以前

https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Collections.Generic/List.cs

などmonoのサンプルを見たので、フィールド変数の頭にアンダースコアをつけるようになったのですが、参考にしないほうがよかったのでしょうか? あと、アンダースコアを使わないとすれば、どうするのがよいでしょうか?

投稿日時 - 2012-02-29 16:30:54

ANo.4

て#2さんのリンク先って
「クラス ライブラリ開発のデザイン ガイドライン」

じゃないですかw
どうも規則(書かれ方)がかつかつすぎないかと思ったらw

これは「後で別のアセンブリから使いまわされるライブラリ」を開発するなら、こういうガイドラインに沿った方がいいだろう
という提案なので


http://msdn.microsoft.com/ja-jp/library/ms229042.aspx

>一貫性のないライブラリ デザインは、開発者の生産性を損なうだけでなく、ライブラリを採用する意欲を失わせます。

「採用する意欲」という言葉からわかるように、これは自分だけで使うものとはちょっと事情が異なります。


なので、koumei000さんがライブラリ作成時の話をされているのなら
この通りでしょうが

exeに入るinternalな感じのクラスとかだったら、もうちょっと自由でいいと思います。

投稿日時 - 2012-02-29 15:46:55

ANo.3

なるほど、C#(というか.NET)は名前のガイドラインまでMSにあるとは
どっぷりMSの管轄って感じですねw

実際には
MS以外の人のサンプルコードではDelegate何々とかよく見かけましたが
MSDNが

>イベント ハンドラーではないデリゲートの名前には、サフィックス Callback を追加します。
>サフィックス Delegate は、デリゲートに追加しないでください。

と書いている、ということは、「Delegate」その物に関しては
将来の拡張予定かなんかがあるのかもしれません。


ネイティブC++にしょっちゅう触っているのでCallbackと言われるとWindowsAPIの事を連想してしまいますが、.NETではイベントハンドラ以外のdelegateで前衛的に使われてる、って感じなんでしょうか。


もちろん、会社とかで独自のやり方があるならそっちの方に優先して合わせた方が良いと思いますが、特に現状そう言う事はないのであれば、MSDNに従っとけば.NETっぽく合わせられるし、将来的な危険も少ないってことでしょうね。(MSの気まぐれは分からんので、「おそらくは」ですが)


個人的には
GettingValueActionで
引数が空でintが戻ってくるというイメージがしにくい(「インスタンス.動作名(とくに~Action)」だと、どっちかっていうと引数をとってそれをもとにインスタンスの内部状態が変わって、引数は関知しない(つまりvoid)っていうイメージ)っていうのがあります。

実際System.Actionデリゲートは戻り値voidですよね


>ただし,EventHandler<T>,ActionやFuncといった汎用のデリゲートがある

そうでした。「ああ、C#」
この場合ですと

戻り値がvoidじゃなくEventHandlerじゃないと仮定して
同じようなことをやるんならFunc<int>で行けませんか?

↓例えばこんなイメージ
using System; //上の方で





sealed class BBB { //たとえなので名前は適当ですが
public Func<int> geti;
public BBB(int i) { geti = () => { return i; }; }
}

class AAA {

protected readonly BBB bbb;

public int Value {
get { return bbb.geti(); }
}

public AAA( BBB bbb_ ) {
bbb = bbb_;
}

}


どっかで
BBB bbb = new BBB(111);

AAA aaa = new AAA( bbb );

なんちゃら = aaa.Value…


などなど

ただ、これが今回適切なのかどうかはもうちょっと広い範囲のコード見ないと何とも言えないです。


もひとつ

protected SampleBox _sampleBox;

この「_」ですが、CやC++だと前方に付けるのは「予約語やdefine等々とのかぶり」の危険が付きまといます。(将来の拡張もかんがえて)

C#だとどうなんでしょう。
と思ってやってみたら
早速

System._AppDomain

うーん、やな予感w
C#でも、前方に付けるのは避けた方が良いんじゃないでしょうかね。

投稿日時 - 2012-02-29 15:10:04

お礼

 ご指摘ありがとうございます。

> 個人的にはGettingValueActionで引数が空でintが戻ってくるというイメージがしにくい(「インスタンス.動作名(とくに~Action)」だと、どっちかっていうと引数をとってそれをもとにインスタンスの内部状態が変わって、引数は関知しない(つまりvoid)っていうイメージ)っていうのがあります。

 慌てすぎました。「GettingValueFanc」の間違いです。

> 同じようなことをやるんならFunc<int>で行けませんか?
 戻り値を持たないくせに引数を増やされるのは速度の面からもよくありませんし、(今回は)コードの見た目も悪くなるので避けています。

> この「_」ですが、CやC++だと前方に付けるのは「予約語やdefine等々とのかぶり」の危険が付きまといます。(将来の拡張もかんがえて)

 実は、この「private」級のフィールド変数の命名には苦心しています。Camel方式ではどうしてもローカル変数とかぶることが多く、自動プロパティの
puclic int Aaa { get; set; } で生成されるフィールド変数、「__aaa」を真似ていた時期もあったのですが、何せ、見た目が汚いので止めました。
 そんなこんなでフィールド変数の形式の模索とリファクタリングで悠に2~3週間累計で消費しおります。
 こちらに関しても、もう少しご意見いただけたら幸いです。

投稿日時 - 2012-02-29 15:44:18

ANo.2

デリゲートの名前については
・イベント用の場合,EventHandlerをサフィックスに付ける
・イベント用以外の場合,Callbackをサフィックスに付ける
というのがMSDNに書いてあります。
http://msdn.microsoft.com/ja-jp/library/ms229040.aspx

ただし,EventHandler<T>,ActionやFuncといった汎用のデリゲートがあるため,
outパラメータやrefパラメータを使う場合を除くと,デリゲートを定義する必要性が乏しいのも事実です。


デリゲート型のプロパティ,というのはあまり例がないのですが,プロパティ自体は基本的に,「名詞・名詞句・形容詞」を付ける,ということになっています。
http://msdn.microsoft.com/ja-jp/library/ms229012.aspx

一応,探すと
MSDN: ServicePointManager.ServerCertificateValidationCallback プロパティ (System.Net)
http://msdn.microsoft.com/ja-jp/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx
というものが出てきます。信頼できない証明書を受け入れるかどうかを決定するためのコールバックです。
これをプロパティとするのはどうかとは思うのですが,デリゲート型のプロパティを作るのであれば上記のようにサフィックス「Callback」を追加するのはよいと思います。

投稿日時 - 2012-02-29 04:49:18

お礼

 解答ありがとうございます。

> ・イベント用以外の場合,Callbackをサフィックスに付けるというのがMSDNに書いてあります。

 はい。すっかり忘れていました。これに従えば「ValueChangedHandler」を見習って、「ValueGettingCallback」(この場合は動名詞じゃなくて、未来の意味を含むing形です)ということになりますよね?
 あと、Actionを参考にして、「ValueGettingAction」、「GettingValueAction」などの型名も思いついたのですが、いかがでしょうか? よろしければ添削をお願いします。

投稿日時 - 2012-02-29 13:32:44

ANo.1

C#にくわしくはありませんが(自分自身の勉強も兼ねて)


C++はよくやるので、そこから判断すると
デリゲートはざっくり言うと関数ポインタみたいなものですから

public delegate int SampleDelegate();

これは、引数なしでint型の変数を戻す、単なる「型」です。

なので、あまり具体的な名前が必要というわけではないというのが普通です。

「この用途で、この辺でだけ使いたい」という事ならpublicにはしないと思いますし
もちろん、GettingValueなどなどは抽象的な名前だと思いますがw

むしろ、「ぱっと見delegateと分かることの方が」ウエイトは大きいかもしれません。

delegateでintをGetするから
DelegGetIntとかでもいいかと。(あくまで例え)
あるいは大文字小文字を自分なりに使い分けて
変数の場合はこういうパターンが多い、クラスの場合はこういうパターンが多い

というのを揃えることは結構大事です。

私がC++で関数ポインタをtypedefするときは全部大文字ってのが多めで、単なる変数は全部小文字にしがちなので、C#にそのまま当てはめると例えばこうでしょうか


private delegate int DELEG_GETINT();
private DELEG_GETINT getvalue;

public int Value {
get { return getvalue(); }
protected set { getvalue = () => { return value; }; }
}


この辺の流儀は自由でしょうが
本当にこだわるなら、色々なサイトや書籍で「概してこうなってるパターンが多い」というものを採用していけば、誰かが見たときも見やすくなる可能性が高いと思います。


少なくともC++では動名詞ってのはそんなに見ない気がしますね。

もちろん全くではないですが
十分クラスごとに機能分割してれば、単なる動詞一個だけでも挙動がだいたい予測できることもありますし。


ただ
getやsetって、通常はこういう感じで使いませんか?

internal sealed class AAA {

readonly string name;
int state;

//プロパティを使わない場合は毎回こうなる恐れがあるので
internal string GetName() { return name; }

internal int State { //stateをprivateにしてState経由でget,set
get { return state; }
set { state = value; }
}

internal void IncrementState(){ ++state; }

internal AAA(string name_) { name = name_; state = 0; }

}

あるいは
http://ufcpp.net/study/csharp/oo_property.html
とかでも

※単なる物のたとえという事ならいいですが

public SampleDelegate SampleAction;

という風に、敢えてSampleActionをpublicにするのなら
SampleActionをそのまま呼び出す、のではだめな状況でしょうか?

投稿日時 - 2012-02-29 02:59:17

お礼

 ご意見、ご指摘ありがとうございます。参考にさせてもらいます。
> DelegGetIntとかでもいいかと。(あくまで例え)
 プレフィックスはなんだか悪いイメージなので「Callback」などのサフィックスにします。

> getやsetって、通常はこういう感じで使いませんか?
 実は初期化時にデリゲート変数入りのオブジェクトを渡してもらって、そのオブジェクトごと「protected」フィールドに代入。そのプロパティ内でオブジェクトからデリゲート変数を読み出して使用、という形を取っているのですが、本項とは直接関係が無いと思い、かなり端折って書かせていただきました。

// ――――――――――――――――――――――――――――

// デリゲート変数を格納
protected SampleBox _sampleBox;


public int Value
{
  get { return _sampleBox.SampleAction(); }
}

public SampleClass(…, SampleBox sampleBox, …)
{
  ……
  _sampleBox = sampleBox;
  ……
}

// ――――――――――――――――――――――――――――

> SampleActionをそのまま呼び出す、のではだめな状況でしょうか?
 「ptotected」の間違いでした。

 「Callback」のサフィックスに従えば「ValueChangedHandler」を見習って、「ValueGettingCallback」(この場合は動名詞じゃなくて、未来の意味を含むing形です)ということになりますよね?
 あと、Actionを参考にして、「ValueGettingAction」、「GettingValueAction」などの型名も思いついたのですが、いかがでしょうか? よろしければ添削をお願いします。

投稿日時 - 2012-02-29 13:50:30

あなたにオススメの質問