• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:c# デリゲート関連の命名について)

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

このQ&Aのポイント
  • c#デリゲート関連の命名についての質問です。SampleDelegateとSampleActionにはどのような名前をつければいいのか悩んでいます。
  • SampleDelegateは値を取得するメソッドを表すので、'~すること'を表す動名詞を使用するのが適切です。SampleActionも同様に、値を取得することを表す名前にするとよいでしょう。
  • 例えばSampleDelegateは'GetValue'、SampleActionは'ValueGetter'という名前を使うことができます。しかし、最終的な命名はコードの読みやすさや一貫性を保つことが重要です。

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

  • ベストアンサー
回答No.27

>結局、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"]/*' /> とかをやっただけでは出ず。 うーむ これが自分のとこでも反応してくれれば最強なんですが これは出来ないのかな?

koumei000
質問者

お礼

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

その他の回答 (26)

回答No.26

あ、そかそか <summary>などなどを使えば C#では解説が出るんでしたねw VC++2008だとインテリセンスに頼れないことが多々あるので、すっかり忘れていました。 このへんのことは既にOKってことですかね? http://ufcpp.net/study/csharp/st_comment.html 仮に 言語について一つだけ表示したい場合は とりあえず開発中は解説が見えなくてもいい! と割り切れるなら、適当に「かぶりそうにない文字を割り当てといて」 後でそいつらを置換するという方法は思いつきますが…

回答No.25

>VerifiedListについて そうですね 一個で済むところなら一個ですました方が断然いいです。 また privateかつreadonlyであるのなら、使用箇所で引数として取るという方法でなくとも、フィールドとして持ってしまっても全体像の可視性は全然よくなってると思います。 >それと後、XMLのコメントのところに「 // 」で区切って日英の両方を書いているのですが、こんな書き方はしないほうが良いのでしょうか?(場合によって<para></para>も使います) それは分かりません。使う人が「こういう風に使う」という仕様書だけ見れば、あとはコード直接見えなくても使えるぐらいなのが、良質なライブラリと言えるので 別途ドキュメント化してしまう方が一般的かもしれません。 ただ、オープンソースにして誰でも改良を施せるようにするなら こういう形式でもいいかもしれません。 その場合は、あとは何らかの テキストエディタ(ソフト)かなんかで、文字の置き換えを簡単に行ってくれるような機能がもしあれば、(無駄ないソースで)日本語用・英語用に別々にリリースするのも可能かもしれません。 >あと、XMLコメントないで「<」の記入に苦労しており、苦しみ紛れに環境依存文字「˂」「˃」で代用していますが、あまり良くないと思います。<xmp></xmp>のようなタグは無いでしょうか? それとも「(in T)」などで代用したほうかよろしいでしょうか? うーん、コメントに関しては全然詳しくないですw 申し訳ない 私はコメントよりソース主義的なところがあって 人のコードを読む時も 1.まずコメントをほとんど読まずに消す 2.自分の読みやすい文法に書き変えながらついでに挙動を追っていく 3.一通り整形し、目を通して尚且つぱっと見で意味が分かり辛い部分があったら、そこではじめて、消した部分に相当する元のソースのコメントを読んでみる という手順を、ほとんど踏むのでw 何しろコメントは間違ったこと書いてても、それを修正するの忘れてても コンパイルエラーにはなりませんからね。 とはいえ、上記のとおり、「オープンソース」かつ「概要説明毎回あり」のケースであれば考えた方が良いかもしれませんが どういうものをどう書きたいところを 今はその部分が<>含め、どうなっているかっていう具体的なところが分かれば、調べられる、かもしれません。

koumei000
質問者

お礼

 回答ありがとうございます。  結局、setとAddは結局同じ動作を含んでいたことに気づいて、Clear、Removeは操作ミスで呼び出されるとしたらユーザーだということに気づきました(それ以外は普通、バグって言いますよね)。  あと、よく考えてみれば何もデリゲートを使わなくてもやりたかったことの一部が出来たんです。 > どういうものをどう書きたいところを今はその部分が<>含め、どうなっているかっていう具体的なところが分かれば、調べられる、かもしれません。  今回のように自前でデリゲートの型を用意した場合、 _sampleAction( ←ここまで入れるとツールチップで変数名が表示されるので 便利なのですが、その変数にラムダ式を代入する場合に引数の型や名前が思い出せず、しぶしぶどこかで上記のよう入力してにツールチップに頼ったりしていたので、それならいっそのこと /// <summary> ///   説明 ///   <para>>>> void Method(int value, List<T> list)</para></summary> private Action<T> _sampleAction; のようにしようと決めたのです…が、なんと、上記の場合「<」がタグ開始として認識されてしまう ということで「˂」「˃」を代用していました(ツールチップ内では「<」「>」より「˂」「˃」の方が違和感が少なかったので使用していますが、「<」「>」でもいいような気がしてきました)。

回答No.24

もうちょい補足です >>Class1はそれを真似たのですが、よくなかったということですか。 >そいつは状況次第ですね。Class1はあくまでユーザー定義の自由なクラスという仮定ならば、ということですが ユーザー定義の自由なクラスでなくても、「設定、取得するものは一種類しかない、配列やリストのような働きをするクラス」や「ハッシュっぽいもの」ならば全く問題ないし むしろ分かりやすいかと思います。

回答No.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 いかがでしょう?

koumei000
質問者

お礼

 ご意見ありがとうございます。 > こういう人は言語に限らず伸びるんですよ。頑張ってください。  はい。ありがとうございます。でも、やっぱり独学では井の中の蛙になってしまうのでこの度は本当に感謝しています。  よくよく考えたのですが、少々凝りすぎていたのかもしれません。そこで間を取って、 /// <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)」などで代用したほうかよろしいでしょうか?

回答No.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

koumei000
質問者

お礼

 ご指摘ありがとうございます 「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」のほうが良かったのかもしれません。

回答No.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に出来るならそれで十分、というだけです。

回答No.20

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

回答No.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

koumei000
質問者

お礼

 ご指摘ありがとうございます。  実は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」になったかと思います。

koumei000
質問者

補足

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

回答No.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 関数とデータは近くに置いてないと無駄に分かりにくくなってしまったりするので (オブジェクト指向に反する) 継承と仮想関数で解決できるんならそれに越したことはないんですが また、「インデクサを使うからには」連想配列的(ハッシュ)的な動きをするとか、そのオブジェクトが配列操作メインの物である ような形じゃないと無駄に分かりにくくなってしまったりすると思います。(上記実験では実際の用途が分からなかったので、最終的なフォームの呼び出し側だけみても分かりにくいコードになっています)

koumei000
質問者

お礼

 ご指摘ありがとうございます。  このような構造にした意図が伝わりづらかったと思うのでまとめさせてもらいます。 ・まず、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の内部で設定しています。

回答No.17

なるほど。 つまり CListActionBox<T> は派生しない使い方が基本的ってことでしょうか? う~ん コードを見て冷静に考えれば考えるほど 実際にどういう状況でこれらのクラスを使いたいのかが分からなくなってきました。 仮想関数では出来ないぐらいに自由な イベントハンドラの任意関数版 を作りたいって感じでしょうか?

koumei000
質問者

お礼

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

関連するQ&A