234

ふざけたタイトルで申し訳ありません。簡潔なタイトルを思いつくことができれば、質問する必要はありません。

不変のリスト型があるとします。Foo(x)最後に余分な要素として指定された引数を持つ新しい不変リストを返す操作があります。したがって、値が「Hello」、「immutable」、「world」の文字列のリストを作成するには、次のように記述できます。

var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");

(これは C# コードです。言語が重要であると思われる場合は、C# の提案に最も関心があります。基本的に言語の問題ではありませんが、言語のイディオムは重要かもしれません。)

重要なことは、既存のリストは変更されないということです。つまり、 0 を返します。Fooempty.Count

最終結果に到達する別の (より慣用的な) 方法は次のとおりです。

var list = new ImmutableList<string>().Foo("Hello")
                                      .Foo("immutable")
                                      .Foo("word");

私の質問は次のとおりです。Foo に最もふさわしい名前は何ですか?

編集 3 : 後で明らかにするように、型の名前は実際には ではない可能性があるためImmutableList<T>、位置が明確になります。代わりに、それがTestSuite含まれているフレームワーク全体が不変であるため、それが不変であると想像してください...

(編集3の終わり)

これまでに思いついたオプション:

  • Add: .NET では一般的ですが、元のリストの変更を意味します
  • Cons:これは関数型言語の通常の名前だと思いますが、そのような言語の経験がない人には意味がありません
  • Plus:これまでのところ私のお気に入りです。私にとって突然変異を意味するものではありません。どうやらこれはHaskell でも使用されているようですが、少し異なる期待があります (Haskell プログラマーは、1 つの値を他のリストに追加するのではなく、2 つのリストを一緒に追加することを期待するかもしれません)。
  • With: 他のいくつかの不変の規則と一致していますが、IMO とまったく同じ「追加性」はありません。
  • And: あまり説明的ではありません。
  • + の演算子のオーバーロード: 私はこれがあまり好きではありません。一般に、演算子は下位レベルの型にのみ適用する必要があると思います。私は説得されても構わないと思っています!

私が選ぶ基準は以下の通りです。

  • メソッド呼び出しの結果の正しい印象を与えます (つまり、余分な要素を持つ元のリストです)。
  • 既存のリストを変更しないことを可能な限り明確にします
  • 上記の 2 番目の例のように連鎖すると妥当に聞こえます

私が十分に明確にしていない場合は、詳細を尋ねてください...

EDIT 1:を好む理由は次のとおりPlusですAdd。次の 2 行のコードを検討してください。

list.Add(foo);
list.Plus(foo);

私の見解では (これ個人的なことですが)、後者は明らかにバグがあります。「x + 5;」と書くようなものです。独自のステートメントとして。最初の行は問題ないように見えますが、不変であることを思い出すまでは。実際、プラス演算子自体がそのオペランドを変更しない方法Plusは、私のお気に入りのもう 1 つの理由です。演算子のオーバーロードのわずかな不快感がなくても、(私にとっては) オペランド (またはこの場合はメソッド ターゲット) を変更しないことを含む同じ意味合いが得られます。

編集 2: Add が気に入らない理由。

さまざまな答えが効果DateTimeStringですReplace。同意します - ここには優先順位があります。DateTime.Addしかし、多くの人がorString.Replaceを呼び出して Mutation を期待しているのを見てきました。たくさんのニュースグループの質問 (そして、掘り下げてみるとおそらく SO の質問) があり、「あなたは の戻り値を無視していますString.Replace。文字列は不変であり、新しい文字列が返されます。」と答えています。

ここで、質問の微妙な点を明らかにする必要があります。型実際には不変リストではなく、別の不変型である可能性があります。特に、テストをスイートに追加すると、新しいスイートが作成されるベンチマーク フレームワークに取り組んでいます。次のことは明らかかもしれません。

var list = new ImmutableList<string>();
list.Add("foo");

何も達成するつもりはありませんが、次のように変更すると、より暗くなります。

var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);

それは大丈夫なようです。これは、私にとって、間違いをより明確にします:

var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);

それはただ物乞いです:

var suite = new TestSuite<string, int>().Plus(x => x.Length);

理想的には、テスト スイートが不変であることをユーザーに伝えなくて済むようにしたいと考えています。成功の穴に落ちてほしい。無理かもしれませんが、やってみたいと思います。

不変のリスト型についてのみ話して、元の質問を単純化しすぎたことをお詫びします。すべてのコレクションが自己記述的であるとは限りませんImmutableList<T>:)

4

75 に答える 75

132

そのような状況では、私は通常、 と一緒に行きConcatます。これは通常、新しいオブジェクトが作成されていることを意味します。

var p = listA.Concat(listB);
var k = listA.Concat(item);
于 2009-02-06T21:22:32.657 に答える
119

1 つの単純な理由から、私は Cons を使用します。

  1. 私は自分の言いたいことを正確に言うのが大好きです。特にソース コードではそうです。初心者は Cons の定義を 1 回だけ調べる必要がありますが、それを何千回も読んで使用する必要があります。初期費用が少し高くても、長期的には、一般的なケースをより簡単にするシステムを使用する方が良いと思います。

  2. FPの経験がない人にとっては「意味がない」という事実は、実際には大きな利点です。あなたが指摘したように、あなたが見つけた他のすべての単語にはすでに何らかの意味があり、その意味はわずかに異なるか、あいまいです. 新しい概念に、新しい単語 (この場合は古い単語) が必要です。Add が何をするかを間違って知っていると仮定するよりも、誰かが Cons の定義を調べる必要があると思います。

  3. 関数型言語から借用した他の操作は、元の名前のままであることが多く、明らかな大惨事はありません。私は、「マップ」と「リデュース」の同義語を、非 FPer にとってより親しみやすいものにしようとする動きを見たことがありませんし、そうすることによる利点も見当たりません。

(完全な開示: 私は Lisp プログラマーなので、 Cons が何を意味するかは既に知っています。)

于 2009-02-06T21:03:37.403 に答える
59

実際And、特に慣用的な方法で、私は好きです。空のリストに静的な読み取り専用プロパティがあり、おそらくコンストラクターをプライベートにして、常に空のリストから構築する必要がある場合は特に気に入っています。

var list = ImmutableList<string>.Empty.And("Hello")
                                      .And("Immutable")
                                      .And("Word");
于 2009-02-06T20:12:41.750 に答える
52

専門用語が詰まっているときはいつでも、インターウェブにアクセスします。

thesaurus.comでは、「追加」に対して次のように返されます。

定義:隣接する、増加する。さらにコメントする

同義語:接辞、附属書、アンティ、追加、増強、強化、ブースト、ビルドアップ、チャージアップ、続行、キューイン、フィギュアイン、フレッシュアウト、ヒートアップ、ハイク、ハイクアップ、ヒッチオン、フックオン、フックアップwith、include、jack up、jazz up、join together、pad、parlay、piggyback、plug into、poor it on、reply、run up、slap on、snowball、soup up、speed up、spike、step up、補足する, 甘くする, つける, タグをつける

Adjoin、またはもっと簡単にの音が好きですJoin。それがあなたがしていることですよね?この方法は、他の の結合にも適用できますImmutableList<>

于 2009-02-06T20:57:56.013 に答える
48

個人的には.With()が好きです。オブジェクトを使用していた場合、ドキュメントまたはコードのコメントを読んだ後、それが何をするのかが明確になり、ソース コードで問題なく読み取れます。

object.With("My new item as well");

または、それに「沿って」を追加します.. :)

object.AlongWith("this new item");
于 2009-02-06T21:02:38.483 に答える
35

BclExtrasのすべての Immutable Collections に対して Add を使用することになりました。その理由は、簡単に予測可能な名前だからです。型の名前には Immutable というプレフィックスが付いているため、Add を変化する add と混同する人がいるという心配はあまりありません。

しばらくの間、Cons やその他の機能的なスタイルの名前を検討しました。最終的にはあまり知られていないため、値引きしました。確かに関数型プログラマーは理解するでしょうが、彼らは大多数のユーザーではありません。

他の名前: あなたが言及した:

  • プラス:私はこれを望んでいます/洗っています. 私にとって、これは Add が行うよりも非変更操作であると区別しません
  • あり: VB で問題が発生します (しゃれが意図されています)
  • オペレーターの過負荷: 検出可能性が問題になる

私が検討したオプション:

  • Concat: 文字列は不変であり、これを使用します。残念ながら、これは最後に追加する場合にのみ有効です
  • CopyAdd: 何をコピーしますか? ソース、リスト?
  • AddToNewList: List に適しているかもしれません。しかし、コレクション、スタック、キューなどはどうですか...

残念ながら、実際にある言葉はないようです

  1. 間違いなく不変の操作
  2. 大多数のユーザーが理解できる
  3. 4 語未満で表現可能

リスト以外のコレクションを考えると、さらに奇妙になります。スタックを例にとってみましょう。初年度のプログラマーでさえ、スタックにはプッシュ/ポップのペアのメソッドがあると言うことができます。ImmutableStack を作成してまったく別の名前を付けた場合、それを Foo/Fop と呼びましょう。コレクションを使用するための作業がさらに追加されたことになります。

編集:プラス編集への応答

Plusでどこに向かっているのかわかりました。より強いケースは、実際には削除のマイナスになると思います。もし私が以下を見たら、プログラマーはいったい何を考えていたのだろうと思うでしょう。

list.Minus(obj);

プラス/マイナスまたは新しい組み合わせで私が抱えている最大の問題は、やり過ぎのように感じることです. コレクション自体には、識別名である Immutable プレフィックスが既にあります。Immutable プレフィックスが既に行ったのと同じ区別を追加することを目的とした語彙を追加して、さらに先に進む必要はありません。

呼び出しサイトの引数が表示されます。単一の表現の観点からそれをより明確にします。しかし、関数全体のコンテキストでは不要に思えます。

編集 2

人々が String.Concat と DateTime.Add によって間違いなく混乱していることに同意します。私は何人かの非常に優秀なプログラマーがこの問題にぶつかるのを見てきました。

ただし、 ImmutableList は別の引数だと思います。String または DateTime について、プログラマにとって不変であると確立するものは何もありません。他のソースを介して不変であることを知っておく必要があります。したがって、混乱は予想外ではありません。

名前がその動作を定義するため、 ImmutableList にはその問題はありません。不変が何であるかを人々は知らないと主張することができますが、それも有効だと思います。確かに大学2年生くらいまで知りませんでした。ただし、追加の代わりに選択した名前には同じ問題があります。

編集 3: TestSuite のような不変であるが単語を含まない型はどうですか?

これは、新しいメソッド名を発明するべきではないという考えを思い起こさせると思います。つまり、並列操作を容易にするために型を不変にする傾向があることは明らかだからです。コレクションのメソッドの名前を変更することに焦点を当てる場合、次のステップは、使用するすべての型で変更できないメソッド名を変更することです。

代わりに、型を不変として識別可能にすることに焦点を当てることは、より価値のある取り組みになると思います。そうすれば、そこにあるすべての変更方法のパターンを再考することなく、問題を解決できます。

では、TestSuite を不変として識別するにはどうすればよいでしょうか? 今日の環境では、いくつかの方法があると思います

  1. 不変のプレフィックス: ImmutableTestSuite
  2. 不変性のレベルを記述する属性を追加します。これは確かに発見されにくい
  3. 他にはあまりありません。

私の推測/希望は、開発ツールが不変の型 (異なる色、より強いフォントなど) を視覚的に簡単に識別できるようにすることで、この問題を解決し始めることです。しかし、すべてのメソッド名を変更しても、それが答えだと思います。

于 2009-02-06T19:54:03.007 に答える
27

+これは、オペレーターのオーバーロードが許容されるまれな状況の 1 つかもしれないと思います。数学用語では、+は何かを他のものの最後に追加しないことを知っています。常に 2 つの値を結合し、新しい結果の値を返します。

たとえば、次のように言うと直感的に明らかです。

x = 2 + 2;

x の結果の値は 22 ではなく 4 です。

同様に、

var empty = new ImmutableList<string>();
var list1 = empty + "Hello";
var list2 = list1 + "immutable";
var list3 = list2 + "word";

各変数が保持するものを明確にする必要があります。が最後の行で変更さlist2れていないことは明らかですが、代わりにに「単語」を追加した結果が割り当てられています。list3list2

それ以外の場合は、関数に Plus() という名前を付けます。

于 2009-02-06T21:27:51.023 に答える
22

できるだけ明確にするために、 wordierCopyAndAddまたは類似のものを使用することをお勧めします。

于 2009-02-06T19:55:03.860 に答える
21

本当に冗長になりたい場合は、 Extend()またはExtendWith()と呼びます。

拡張とは、何かを変更せずに他の何かに追加することを意味します。これは拡張メソッドの概念に似ているため、これはC#の非常に関連性の高い用語だと思います。つまり、クラス自体に「触れる」ことなく、新しいメソッドをクラスに「追加」します。

それ以外の場合、元のオブジェクトをまったく変更しないことを本当に強調したい場合は、Get-のようなプレフィックスを使用することは避けられないように見えます。

于 2009-02-06T20:01:37.857 に答える
18

私はCopyAndAddのmmyers提案が好きです。「突然変異」のテーマに沿って、Bud(無性生殖)、GrowReplicate、またはEvolveを使用できますか?=)

編集:私の遺伝的テーマを続けるために、Procreateはどうですか?前のオブジェクトに基づいているが、何か新しいものが追加された新しいオブジェクトが作成されることを意味します。

于 2009-02-06T20:03:12.800 に答える
18

追加()、追加()

不変オブジェクトの操作には過去形を使用するのが好きです。元のオブジェクトを変更していないという考えが伝わり、見たときに簡単に認識できます。

また、変更メソッド名は現在時制の動詞であることが多いため、不変メソッド名が必要なケースのほとんどに適用されます。たとえば、不変スタックには「pushed」および「popped」メソッドがあります。

于 2009-02-06T21:34:15.207 に答える
14

これはおそらく大雑把ですが、Ruby では区別のために一般的に使用される表記法がありaddます。add!変異します。これがプロジェクトに蔓延する問題である場合は、それも行うことができます (必ずしもアルファベット以外の文字を使用する必要はありませんが、変化する方法と変化しない方法を示す表記法を一貫して使用します)。

于 2009-02-06T22:48:28.737 に答える
13

Join適切なようです。

于 2009-02-06T22:42:17.330 に答える
13

おそらく混乱は、2 つの操作を 1 つにまとめたいという事実から生じているのでしょう。それらを分離しないのはなぜですか?DSL スタイル:

var list = new ImmutableList<string>("Hello");
var list2 = list.Copy().With("World!");

Copy元のリストの変更可能なコピーである中間オブジェクトを返します。With新しい不変リストを返します。

アップデート:

しかし、中間の変更可能なコレクションを持つことは、良いアプローチではありません。Copy操作には中間オブジェクトが含まれている必要があります。

var list1 = new ImmutableList<string>("Hello");
var list2 = list1.Copy(list => list.Add("World!"));

現在、Copy操作は、変更可能なリストを受け取るデリゲートを使用して、コピーの結果を制御できるようにします。要素の削除やリストの並べ替えなど、要素を追加するだけではありません。コンストラクターで使用して、ImmutableList中間の不変リストなしで初期リストを組み立てることもできます。

public ImmutableList<T> Copy(Action<IList<T>> mutate) {
  if (mutate == null) return this;
  var list = new List<T>(this);
  mutate(list);
  return new ImmutableList<T>(list);
}

これで、ユーザーが誤解する可能性はなくなり、ユーザーは自然に成功の穴に落ちます。

さらに別の更新:

変更可能なリストへの言及が気に入らない場合は、それが含まれているにもかかわらず、コピー操作がそのリストをどのように変換するかを指定する仕様オブジェクトを設計できます。使い方は同じです:

var list1 = new ImmutableList<string>("Hello");
// rules is a specification object, that takes commands to run in the copied collection
var list2 = list1.Copy(rules => rules.Append("World!"));

Copyこれで、ルール名を工夫して、 の機能全体ではなく、サポートしたい機能のみを公開できますIList

チェーンの使用法については、合理的なコンストラクターを作成できます (もちろんチェーンは使用しません)。

public ImmutableList(params T[] elements) ...

...

var list = new ImmutableList<string>("Hello", "immutable", "World");

または、別のコンストラクターで同じデリゲートを使用します。

var list = new ImmutableList<string>(rules => 
  rules
    .Append("Hello")
    .Append("immutable")
    .Append("World")
);

rules.Appendこれは、メソッドが を返すことを前提としていますthis

これは、最新の例では次のようになります。

var suite = new TestSuite<string, int>(x => x.Length);
var otherSuite = suite.Copy(rules => 
  rules
    .Append(x => Int32.Parse(x))
    .Append(x => x.GetHashCode())
);
于 2010-02-07T05:31:24.743 に答える
11

いくつかのランダムな考え:

  • ImmutableAdd()
  • 追加()
  • ImmutableList<T>(ImmutableList<T> originalList, T newItem) コンストラクター
于 2009-02-06T19:56:44.420 に答える
10

C# の DateTime は Add を使用します。では、なぜ同じ名前を使用しないのでしょうか。クラスのユーザーがクラスが不変であることを理解している限り。

于 2009-02-06T19:55:32.083 に答える
9

表現するのが難しい重要なことは、非置換であるため、CopyWith() や InstancePlus() などの生成的な単語が含まれている可能性があります。

于 2009-02-06T20:07:11.903 に答える
9

英語では、「追加」と同じ意味の動詞を使用しているときに、紛れもない方法で不変性を暗示することはできないと思います。「プラス」はほぼそれを行いますが、それでも人は間違いを犯す可能性があります。

ユーザーがオブジェクトを変更可能なものと間違えないようにする唯一の方法は、オブジェクト自体の名前またはメソッドの名前を使用して明示的にすることです (「GetCopyWith」や"CopyAndAdd")。

お気に入りの「プラス」をどうぞ。

于 2009-02-06T20:36:08.707 に答える
9

まず、興味深い出発点: http://en.wikipedia.org/wiki/Naming_conventions_(programming) ...特に、下部にある「関連項目」リンクを確認してください。

私は Plus か And のどちらかを、事実上同等に支持します。

Plus と And はどちらも語源が数学に基づいています。そのため、どちらも数学的操作を意味します。どちらも、戻り値を持つメソッドに適合する値に解決される可能性のある式として自然に読み取れる式を生成します。 Andには追加の論理的意味合いがありますが、どちらの単語も直感的にリストに当てはまります。 Addメソッドの不変のセマンティクスと矛盾する、オブジェクトに対して実行されるアクションを意味します。

どちらも短く、これは操作の原始性を考えると特に重要です。単純で頻繁に実行される操作には、短い名前を付ける必要があります。

不変のセマンティクスを表現することは、私がコンテキストを介して行うことを好みます。つまり、このコード ブロック全体が機能的な感覚を持っていることを単純に暗示したいと思います。すべてが不変であると仮定します。しかし、それは私だけかもしれません。私は不変性がルールであることを好みます。それが完了した場合、同じ場所で多くのことが行われます。可変性は例外です。

于 2009-02-06T21:30:17.647 に答える
7

私はプラス(およびマイナス)が好きです。それらは簡単に理解でき、よく知られている不変の型(数値)を含む操作に直接マップされます。2 + 2は2の値を変更せず、同じように不変の新しい値を返します。

他のいくつかの可能性:

スプライス()

Graft()

Accrete()

于 2009-02-07T00:18:56.963 に答える
6

従う人のために、 matemateWith、またはcoitusはどうですか。生殖に関しては、哺乳類は一般的に不変であると考えられています。

ユニオンもそこに放り出すつもりです。SQL から借用。

于 2009-02-06T22:24:15.667 に答える
6

どうやら私は、この質問に答えた最初の Obj-C/Cocoa 関係者です。

NNString *empty = [[NSString alloc] init];
NSString *list1 = [empty stringByAppendingString:@"Hello"];
NSString *list2 = [list1 stringByAppendingString:@"immutable"];
NSString *list3 = [list2 stringByAppendingString:@"word"];

これでコードゴルフゲームに勝つつもりはありません。

于 2010-02-09T14:11:48.773 に答える
5

「追加」または「プラス」がいいと思います。リスト自体の名前は、リストの不変性を伝えるのに十分なはずです。

于 2009-02-06T19:57:15.200 に答える
5

Plus()and Minus()or, あるいは, Including(),は、不変の振る舞いを暗示するExcluding()点で合理的だと思います。

ただし、命名の選択によってすべての人に完全に明確になることはないため、個人的には、優れた xml doc コメントがここで非常に役立つと信じています。VS は、IDE でコードを記述するときにこれらを目の前に投げます。無視するのは困難です。

于 2009-06-11T22:25:29.977 に答える
5

たぶん、インスタンスを変更する代わりに、コピーを作成してそれに何かを追加することをもっと覚えている単語がいくつかあります(「連結」など)。しかし、他のアクションの言葉にも対称性があるとよいと思います。「連結」と同じ種類の「削除」に似た言葉を私は知りません。「プラス」は私には少し奇妙に聞こえます。数値以外のコンテキストで使用されるとは思いません。しかし、それは私の英語以外のバックグラウンドから来ている可能性もあります.

多分私はこのスキームを使用します

AddToCopy
RemoveFromCopy
InsertIntoCopy

しかし、考えてみると、これらには独自の問題があります。与えられた引数に何かを削除したり、何かを追加したりすると考えることができます。それについてはまったくわかりません。それらの言葉は、チェーン化でもうまく機能しないと思います。入力するには長すぎます。

多分私は普通の「追加」と友達も使うでしょう。数学での使い方が好き

Add 1 to 2 and you get 3

確かに、2 は 2 のままで、新しい数が得られます。これは 2 つの数字についてであり、リストと要素についてではありませんが、いくつかの類推があると思います。私の意見でaddは、必ずしも何かを変異させるという意味ではありません。addだけを含み、返された新しいオブジェクトを使用しない孤独なステートメントを持つことは、バグに見えないというあなたの主張を確かに理解しています。しかし、「追加」以外の名前を使用するというアイデアについてもしばらく考えましたが、別の名前を思いつくことはできません。その名前は、私が期待する「追加」とは異なるためです。litb からのこれについての奇妙な考えだけで、まったく意味があるかどうかはわかりません :)

于 2009-02-06T21:11:29.573 に答える
5

http://thesaurus.reference.com/browse/addhttp://thesaurus.reference.com/browse/plusを見ると、ゲイン接辞が見つかりましたが、それらが非変異をどの程度暗示しているかはわかりません。

于 2009-02-07T14:58:06.707 に答える
4

Append-なぜなら、System.Stringメソッドの名前は、インスタンスを変更することを示唆していますが、そうではないことに注意してください。

または私はとても好きAfterAppendingです:

void test()
{
  Bar bar = new Bar();
  List list = bar.AfterAppending("foo");
}
于 2009-02-06T20:02:37.620 に答える
3

私は個人的に好きunite()です。オブジェクトを結合すると、それらの個性は維持されますが、それらの結合は別の新しいエンティティになります。Union提案されているように似ていますが、すでに集合論で明確に定義されており、uniteより冗長であり、この方法に従うと新しい実体があると私に言います. 遅いことはわかっていますが、リストに提案が見つかりませんでした。さらに、この言葉は、戦争に行くために人々を団結させた昔の時代を思い出させます..へへ

于 2010-09-30T13:14:36.597 に答える
3

おそらく、静的メソッドまたは演算子 (静的) が最適です。インスタンスから責任を奪い、ユーザーは操作がどのインスタンスにも属していないことをすぐに知ることができます。拡張メソッドを使用しないことが特に重要です。使用時のインスタンス メソッドとの類似性が目的を損なうためです。

静的メソッドを呼び出すことができますJoin:

public static class ListOperations {
  public static ImmutableList<T> Join<T>(ImmutableList<T> list, T tail) {
    // ...
  }
  public static ImmutableList<T> Join<T>(T head, ImmutableList<T> list) {
    // ...
  }
  public static ImmutableList<T> Join<T>(ImmutableList<T> list1, ImmutableList<T> list2) {
    // ...
  }
  // substitutes chaining:
  public static ImmutableList<T> Join<T>(ImmutableList<T> list, params T[] tail) {
    // ...
  }
}

// ....

var list = new ImmutableList<string>("Hello");
var list2 = ListOperations.Join(list, "immutable"); // inferred type parameter
var list3 = ListOperations.Join(list2, "world!");

しかし、ここでは C# にクラスフリー関数があればいいのにと思います。または、少なくとも Java の静的インポート機能のようなものです。

演算子は次のようになります+

var list = new ImmutableList<string>("Hello");
var list2 = list + "immutable";
var list3 = list2 + "world!";

しかし、C# では不可能な<<::または などの他のものを使用できるようにしたいと考えています。.

また、静的メンバーはより機能的に見えるので、この不変ビューにより適していると思います。

于 2010-06-04T19:43:01.017 に答える
3

より良い名前の利点を理解できるので、私は Add に行きますが、問題は、他のすべての不変操作に対して異なる名前を見つけることです。

于 2009-04-17T18:39:15.590 に答える
2

WithAddedという名前は読みやすく、形容詞として読むことができる追加よりもIMHOの方が優れています。

var list2 = list1.WithAdded("immutable");

または、もう少し冗長なバージョンの場合:

var list2 = list1.WithAddedElement("immutable");
于 2011-05-20T22:54:34.643 に答える
2

list.NewList("word")あなたが何をしているのか(新しいリストを作成する)を説明しているので、私は一緒に行きます。

引数がリストの最後に追加されることを意味するものではないことに同意する必要がありますが、個人的には可能であれば簡潔なキャンプに属しているためlist.NewList("word")list.NewListAfterAppend("word").

于 2011-09-21T19:22:29.803 に答える
2

私はパーティーに少し遅れましたが、まったくやらないことを提案する答えは見当たりませんでした! 不変のままにしましょう。あなたが入れたメソッドは、彼らがそれをループに入れたときに悪用される可能性があり、それは最終的に ~will~ 起こります。代わりに、代わりにビルダーを使用することをお勧めします。

MyImmutableBuilder builder = new MyImmutableBuilder(someImmutable);
MyImmutable modifiedImmultable = builder.add(element1).add(element2).build();

ImmutableList の場合、ほとんどの場合、ビルダーは実際にはただのリストになります。

結局のところ、不変のコレクションに要素を 1 つだけ追加する簡単な方法が本当に必要ですか? 頻繁に発生する場合は、おそらく不変オブジェクトを使用したくないでしょう (build()オブジェクトの現在の状態のスナップショットを送信したい場合はいつでも呼び出すことができます...)。それを行うための要件としてビルダーを使用することは、特にこれがビルド方法であることが文書化されている場合は、大きな障害にはなりません。

@supercat - あなたが説明する次のシナリオを検討してください。

Stack a = someImmutableStackOfSize(10);
Stack b = a.popAndCopy(); // size 9
Stack c = a.popAndCopy(); // also size 9
// a b and c have the same backing list
Stack d = b.pushAndCopy("node1");
Stack e = c.pushAndCopy("node2");
// because d and e had the same backing list, how will it 
// know that d's last element is node1, but e's last
// element is node2?
于 2011-06-22T20:34:03.380 に答える
2

どうcloneWithですか?

理由:
1. 提案された単一の単語名については、ドキュメントを確認するまで、その単語が何をするものなのかわかりません。
2. これまでに提案された化合物名については、私の方が好きcloneWithです。このメソッド名で何が得られたかを正確に知ることができます。比較的簡潔で、覚えやすく、正しく「感じる」だけです:)
3.ほとんどのプログラミングツールの最新のコード補完により、長い名前は簡単にこれまで以上に働きます。

多くの場合、簡潔さが明快さを増しますが、選択する必要がある場合は、簡潔さよりも明快さを優先してください...

実際に:

var empty = new ImmutableList<string>();
var list1 = empty.cloneWith("Hello");
var list2 = list1.cloneWith("immutable");
var list3 = list2.cloneWith("word");
于 2011-05-17T16:42:23.617 に答える
1

これは、オブジェクトが変更されていないことを表す単語を見つけることに帰着するようです。また、それが複製され、パラメーターとして渡された要素が複製されたリストの末尾に追加されます。のような標準的な名前はaddclone決してそれをカバーするつもりはありません。この部分は、パラメーターが元のリストに追加されていることを暗示している可能性があるため、おそらくclone_and_appendこれもかなりあいまいです。appendしたがって、これはおそらく のようなものか、clone_and_append_to_cloneそれよりも優れたものになるはずですappend_to_cloneが、これは、このメソッドによってクローンが返されることを実際に意味するのではなく、クローンが元のリストの一部として既に存在することを意味します。

したがって、元のリストへの変更を意味せず、新しいリストが作成されることを示唆する名前を見つける方法に沿ってさらに考えて、次のことを検討してください。

  1. オフシュート-- var list1 = list.Offshoot("tail")- 厳密な意味では、オフシュートはここでは新しい要素を指し、新しいリスト全体ではありません。もう 1 つの明らかな欠点は、アクションではないことです。より正確な名前はlist.CreateOffshootです。ただし、新しいリストに元のリストが含まれ、新しい要素がリストの最後に来るという事実を明確に示していることがわかりました。
  2. スポーン-- var list1 = list.Spawn("tail")- 前と同様。利点はそれがアクションであることですが、新しいリストに元のリストが含まれるというより弱い含意があります。
  3. BranchOff -- var list1 = list.BranchOff("tail")- 元のリストが複製されることを示唆するアクション。潜在的なあいまいさの 1 つは、パラメーター要素がどのように使用されるかがあまり明確でないことです。
于 2011-07-01T09:35:07.663 に答える
1

関数型プログラマーの場合、これにはいくつかの名前があります。

(++)

「アペンド」と発音します。またはconcat、タイプに応じて、次のようになります。

-- join two things into one thing:
append :: a -> a -> a    

-- join many things into one thing
concat :: [a] -> a

または(:)、別名cons:

(:) :: a -> [a] -> [a]    

リストの先頭に追加するsnoc場合、最後に追加する場合。

少なくとも、過去 20 年間、Haskell ランドでリストに追加することを私たちはそう呼んできました。


(+)これはリングではなくモノイダルであるため、算術演算ではないことに注意してください。

于 2011-05-20T07:02:30.937 に答える
1

copyWithSuffix:Objective-C の不変文字列コピー メソッドと同様のカスタム メソッド名になりますstringByAppendingString:

var suite = new TestSuite<string>();
suite = suite.CopyWithSuffix("Str1")
             .CopyWithSuffix("Str2")
             .CopyWithSuffix("Str3");

Suffixその追加性を伝えCopy、不変性を明確にします。実際のテストスイートの種類に合わせて、より論理的なものに自由に置き換えSuffixてください(おそらく、これらを1つの大きな内部文字列に接尾辞を付けていないかもしれません。私が知っているすべてのテストケース名/パラメータを提供している可能性があります)。

于 2011-08-03T00:56:15.213 に答える
1

メソッドに正しく名前を付けると、誤用の可能性を減らすことができますが、コンパイラに「このメソッドは新しいオブジェクトを返すだけで何もしません。使用する必要があります。そうしないと、メソッド呼び出しは無意味です」と伝える言語構造があった場合、コンパイラは可能性があります。誰かが間違ったセットアップでメソッドを使用するたびに、エラー/警告で文句を言います。

この機能のリクエストに記入しました。同意する場合は、自由に投票してください。

于 2015-08-28T18:16:27.547 に答える
1

私は個人的に、AddVoidまたはその逆に行きますVoidAdd

于 2011-02-03T22:22:50.257 に答える
1

同じ型のオブジェクトが返されることを意味する名前であれば、問題なく使用できます。2 つのオブジェクトを足すと、結果が返されることが期待されるため、プラスはこれに適した名前です。

ただし、テストをテストスイートに「プラス」しているため、プラスはこのインスタンスで使用する正しい名前のようには聞こえません。

GetWith() はオプションのように聞こえます。または、型が明らかに使用している型である GetTypeWith() 。たとえば、次のようになります。

var list = new ImmutableList<String>();
var list2 = list.GetWith("First");
var list3 = list2.GetWith("Second");

// OR

var list2 = list.GetListWith("First");

Get は、既に含まれているリストを取得していることを意味し、With は、それと一緒に別のオブジェクトが必要であることを意味します。CopyWith() もこの基準を満たします。

私が GetWith で目にする差し迫った問題は、簡単に推測できないことです。開発者は、現在のスイートを取得するのではなく、スイートを追加したいと考えています。私はすぐに .Add と入力し、インテリジェンスが私が期待したものに非常に近いものを示したことを願っています。

于 2009-04-04T07:01:35.453 に答える
1

C++ プログラマーおよび STL のファンとして、私はadd_copy. (これは なども示唆remove_copyreplace_copyます)

于 2010-02-25T19:35:42.080 に答える
1

1)質問の質問分析
の要約は次のとおりです:
不変から...新しい不変を取得しますが、元のものとは異なります..
この現在の質問のコンテキストでは:
不変リストから新しいの違いを持つ新しい不変リストを取得します最後に要素を追加します。

単純な「追加」動詞を使用せずにアクションを簡潔に表現する効果的な「動詞」(プログラミング言語の「メソッド」) を教えてください。

2) 提案分析
最初の概念: 不変は同様の不変を与える ,
>>"コピー" 動詞は "内容" で保存を表現するが、それが制約を定義している (不変)
>>"クローン" 動詞は "内容" で保守を表現するが、その定義された制約。
>>"twin" 動詞は clone に似ていますが、ソフトウェアでは一般的ではありませんが、短くて響きが良いです。

2 番目の概念: 結果は元のオブジェクトとは異なるものを与える
>>"追加"は、元のオブジェクトと新しいオブジェクトを区別するアクションを表しますが、定義上、不変のアクション (変更) は行いません。
>元のオブジェクトを乱すことなく動詞の結果が拡張されるという事実を表現します... "副詞" アプローチはより "不変"
フレンドリーですそれが何をするかについて。 「動詞パラメータ」 が「

動詞」の「より多く」であること表現できます>> extendsCloneWith 動詞 "twin"付き >>augTwin >>

















>> growTwinWith
>> extendTwinWith

于 2011-08-26T08:47:20.417 に答える
0

この種の関数では、私は通常Added、この場合、2番目の形式の動詞を使用します。

この規則はQtで使用されます。たとえば、正規化されたQVector2D::normalizedベクトルを返し、ベクトルをQVector2D::normalize正規化します。

同様Addedに、新しく追加されたアイテムを含むオブジェクトを返します。

于 2010-11-22T12:52:35.617 に答える
0

"交換"?リストに追加されるのではなく、リストを新しいものに置き換えます。

于 2009-02-06T20:00:40.807 に答える
0

単純なAdd()を使用します。これが実際に収集操作であることを伝えたい場合は、代替手段としてAppend()を使用します。

明示的な方法に加えて、obverloaded+operatrを実装することをお勧めします。これはよく知られている操作です。Stringが不変であることは誰もが知っていますが、誰もが「+」を使用してStringの新しいインスタンスを構築します。

于 2009-02-06T20:02:26.077 に答える
0

「オーグメント」はどうですか?

Addとは別の言葉ですが、密接な同義語です。

于 2009-02-06T20:05:53.700 に答える
0

list.copyAndAppend(elt)

それはどのように聞こえますか?)

于 2010-03-03T18:25:28.803 に答える
0

ゲームに非常に遅れていますが、どうですかFreeze。WPF では、オブジェクトが変更可能かどうかを使用Freezeおよびテストするための優先順位があります。IsFrozen確かに、これは通常Freeze()、現在のオブジェクトを不変にする方法として意図されているという意味で少し意味を歪めますが、それにパラメーターがある場合は、不変なものを取得していることがわかります。

var list = new ImmutableList<string>().Freeze("Hello")
                                      .Freeze("Fridgid")
                                      .Freeze("World");

基本的:

  1. 一言です
  2. その意味合いは、不変性を中心に展開しています。
  3. 「類似」構文の WPF での優先順位。
于 2009-04-15T21:24:40.860 に答える
0

「Stick」または「StickTo」はどうですか、要素を最後に貼り付けます。

または「アタッチ」または「アタッチ先」。

于 2009-02-08T14:38:03.873 に答える
0

これが一見死んだ馬を打ち負かしていることは知っていますが、奇妙な方法でこれに取り組んでいる可能性があると思います(したがって、命名が困難です)。不変オブジェクトがある場合、そのオブジェクトに可変性を意味する関数 (Add や AddAll など) があるとは思いません。String と DateTime がこれを行うことは知っていますが、DateTime / String 関数の結果を使用するのを忘れてしまったので、可能であればこれらの落とし穴を避けたいと思います。

私があなたなら、Guava が使用するものと同様の Builder パターンに従います。Guava の不変コレクションを参照してください。基本的には、これまでに含まれるすべてのものを使用して不変オブジェクトを構築するという概念です。新しい不変オブジェクトを作成する場合は、新しいビルダーを使用する必要があります。

var suite = new TestSuite.Builder<string, int>().add(newTest).build();

ビルダーを拡張して、ユーザーがビルドを呼び出す前に、(必要に応じて追加/削除などの標準的なリスト命名規則を使用して) テスト スイートにさまざまな変更を加えることができます。

于 2012-01-10T18:48:22.320 に答える
0

And() が好きです。あいまいさの可能性は最も少ないと思います。私が考えることができる唯一の衝突は、論理的なものですそして、それが C# 開発者の問題であるとは思いませんし、VB でさえ、コンテキストが問題を引き起こす可能性が低く、問題がすぐに取り上げられると思いますコンパイル時間。また、英語の「Do something to These And That」または「Put These And That in the box」にも適しています。

.With() は OKだと思います。私の懸念は、特に引数としてラムダがある場合、linq Where<> メソッドのように見えるかもしれないということです。私の頭の中の英語もあまり明確ではありません。特に「Do something to These With That」です。

私は .Plus() が好きではありません。Add の同義語としてそれを通り抜けることはできません: plus = plus sign = + = add.

于 2009-02-06T19:55:06.997 に答える
0

非常に遅い答えですが、私は2セントを追加したかったのです.ここでのポイントは、動詞自体よりも動詞の時制である可能性があると思います.

var output= myList.joinedWith("Element"); //or AddedTo, ConcatenatedTo...

私の意見では、分詞によって意味が変わります。myList に何も追加するのではなく、操作の結果を返すということです。

于 2014-10-08T16:31:32.537 に答える
0

「CreateNewListWithAdditionalItems」を使用します

長い名前は気にしませんが、これは実際に何をするかを示しています。また、Add またはその他の変更方法を使用すると、例外がスローされます。

于 2010-11-23T17:02:58.930 に答える
0

個人的には、おそらく流暢なスタイルを求めている場合は、Pad(..) を使用し、AndWith(..) の拡張メソッドも使用します。

var list = new ImmutableList<string>().Pad("Hello")
                                      .AndWith("immutable")
                                      .AndWith("word");
于 2011-11-16T22:04:51.093 に答える
0

型名は ImmutableList であり、事実上不変であることを示しているので、 .Add() は問題ないと思います。しかし、あなたが何か他のことを本当に主張しているなら、私は .AddEx() のようなものを使うかもしれません。Ex は拡張を意味し、ユーザーは使用する前にその Ex が何であるかを (ドキュメントを読んで) 判断する必要があることを意味します。Plus() と GetCopyWith() の提案も気に入っています

于 2009-02-06T20:34:50.363 に答える
0

Cから拝借、いかがですかConcat

于 2011-01-07T18:55:31.043 に答える
0

個人的には、メソッドCloneを呼び出してパラメーターを呼び出します。AdditionalValueこれは、本質的にそれが行っているように見え、簡単に理解できるからです。

var empty = new ImmutableList<string>(); 
var list1 = empty.Clone("Hello"); 
var list2 = list1.Clone("immutable"); 
var list3 = list2.Clone("word");
于 2010-05-24T10:07:45.130 に答える
0

C# 風の疑似コードは次のとおりです。

interface Foo
{
    // Constructors
    Foo();
    Foo(params Foo[] foos);

    // Instance method
    Foo Join(params Foo[] foos);

    // Class method
    static Foo Join(params Foo[] foos);
}    

したがって、次のように呼び出すことができます。

var f0 = new Foo();
var f1 = new Foo(new Foo(), new Foo(), new Foo());
var f2 = Foo.Join(new Foo(), new Foo(), new Foo());
var f3 = f0.Join(new Foo(), new Foo(), new Foo());
var f4 = new Foo(new Foo(new Foo()), new Foo(), new Foo(new Foo()));

等....

于 2009-06-26T12:43:40.747 に答える
0

.Trail は、リストの非常に強い理解が変更されていないことを意味します。このオブジェクトはリストの後ろにあり、リストに追加されていません。

var list = new ImmutableList<string>().Trail("Hello");
                                      .Trail("immutable");
                                      .Trail("word");
于 2009-02-06T21:09:57.050 に答える
0

前述のように、一度に 2 つのことを実行しようとしており、その目的のためだけにマイクロ最適化を行っています。元のコレクション定義から離れてコピーが発生した場合、「追加」、「追加」などの名前は混乱するだけです。

CloneAppend」は、この状況で使用できるものです。このような状況にはならないだろうと何かが教えてくれます。「 CloneFirstN」や「CloneRemoveLast 」など、他の種類の同様の操作がすぐに必要になると思います。そしてすぐに、clone/copy メソッドを連鎖させ、必要なものを追加/削除してから、余分なコード行が必要であっても、コレクションを不変に戻す方がはるかに優れていることに気付くでしょう。

于 2010-04-24T22:59:22.650 に答える
0

この質問は基本的に類義語辞典になっているので: How about .Bring(). のように、私にこのリストを渡して、この要素を持ってきてください。

Foo = List.Bring('short');
          .Bring('longer');
          .Bring('woah');

それは舌から転がり落ちることはありませんが、それは私にとってそれを意味します.

実際には、AndBring()もっと良いかもしれません。

于 2009-10-08T04:58:29.097 に答える
0

"追加()"

それが新しいリストを返すという事実は重要ではなく、署名によって実装の詳細が明らかになります。メソッドが実行する主なアクションは、新しい要素をリストに「追加」することです。どのように、または何を取得または返すかは、メソッド名の一部であってはなりません。メソッドが同期された場合、それはメソッド名に影響します -"synchronizedAdd()" ??? - もちろん違います。

ミューテーターになりそうなパターンに従う String のようなクラスは、依然として非常に単純なメソッド名を持っています - どれも複合語ではありません。

于 2009-02-06T21:14:48.537 に答える
0

私はそれをToIncludeと呼びます

var empty = new ImmutableList<string>();
var list1 = empty.ToInclude("Hello");
var list2 = list1.ToInclude("immutable");
var list3 = list2.ToInclude("word");

慣用的に(?)

var list = new ImmutableList<string>().ToInclude("Hello");
                                      .ToInclude("immutable");
                                      .ToInclude("word");

あなたが言及したケースでも機能します。

var list = new ImmutableList<string>();list.ToInclude("foo");

var suite = new TestSuite<string, int>();suite.ToInclude(x => x.Length);
于 2009-03-11T15:00:57.813 に答える
0

私はコンストラクタを使用します。

Foo f1 = new Foo("one");
Foo f2 = new Foo(f1, "two");
Foo f3 = new Foo(f2, "three");

f1 には「1」が含まれます。f2 には「1」、「2」が含まれます。f3 には、「1」、「2」、「3」が含まれます。

于 2009-02-08T15:16:11.520 に答える
0

Augment(またはAugmentWith) メソッドを使用してラッパー クラスを作成するのはどうですか?

于 2009-08-03T11:49:18.133 に答える
0

のようなメソッドの問題String.Replaceは、ユーザーが戻り値を無視できるため、突然変異が起こっていると誤って考える可能性があることです。outそのため、「戻り値」にはパラメーターを使用してください。ユーザーはそれを無視できませ:

public class ImmutableList<T> {
  public ImmutableList(params T[] items) { 
    // ...
  }
  /// <summary>
  /// Creates a new list with the items in this list plus the supplied items.
  /// </summary>
  /// <param name="newList">
  /// The new list created for the operation.
  /// This is also the return value of this method.
  /// </param>
  /// <param name="items">Items to add to the new list.</param>
  /// <returns>The new list.</returns>
  public ImmutableList<T> Add(out ImmutableList<T> newList, params T[] items) {
    // ...
  }
}

使用法:

var list = new ImmutableList<string>("Hello", "Immutable");
ImmutableList<string> newList;
list.Add(out newList, "World");
于 2011-03-03T14:45:21.583 に答える
0

演算子のオーバーロードを使用し+ます。その理由は、それが Python での動作方法だからです。.append()あるリストで行うとリストが変更され+、別のリストで行うと新しいリストが作成されます。+また、間違いなく突然変異を意味するものではありません。それがあなたがとても好きな理由だと思う.Plus()ので、演算子のオーバーロードをしたくない場合は、.Plus().

于 2010-02-07T18:29:01.527 に答える
0

「ImmutableAdd()」という名前のメソッドは単純すぎると思いますか?

于 2009-02-06T23:44:49.623 に答える