it-swarm.com.de

Was ist der beste Name für eine nicht mutierende "Add" -Methode in einer unveränderlichen Sammlung?

Entschuldigung für den Waffeltitel - wenn ich einen prägnanten Titel finden könnte, müsste ich die Frage nicht stellen.

Angenommen, ich habe einen unveränderlichen Listentyp. Es hat eine Operation Foo(x), die am Ende eine neue unveränderliche Liste mit dem angegebenen Argument als zusätzliches Element zurückgibt. Um eine Liste von Strings mit den Werten "Hallo", "unveränderlich", "Welt" zu erstellen, könnten Sie schreiben:

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

(Dies ist C # -Code, und ich bin am meisten an einem C # -Vorschlag interessiert, wenn Sie der Meinung sind, dass die Sprache wichtig ist. Es handelt sich nicht grundsätzlich um eine Sprachfrage, aber die Redewendungen der Sprache können wichtig sein.)

Wichtig ist, dass die vorhandenen Listen nicht durch Foo geändert werden - also würde empty.Count Immer noch 0 zurückgeben.

Ein anderer (idiomatischerer) Weg, zum Endergebnis zu gelangen, wäre:

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

Meine Frage ist: Was ist der beste Name für Foo?

EDIT 3 : Wie ich später verrate, ist der Name des Typs möglicherweise nicht wirklich ImmutableList<T>, Was die Position klar macht. Stellen Sie sich stattdessen vor, dass es TestSuite ist und dass es unveränderlich ist, weil das gesamte Framework, zu dem es gehört, unveränderlich ist ...

(Ende der Bearbeitung 3)

Optionen, die ich mir bisher ausgedacht habe:

  • Add: In .NET üblich, impliziert jedoch eine Mutation der ursprünglichen Liste
  • Cons: Ich glaube, dies ist der normale Name in funktionalen Sprachen, aber für diejenigen ohne Erfahrung in solchen Sprachen bedeutungslos
  • Plus: Mein bisheriger Favorit, bedeutet für mich keine Mutation . Anscheinend ist dies auch in Haskell verwendet , jedoch mit leicht unterschiedlichen Erwartungen (ein Haskell-Programmierer erwartet möglicherweise, dass zwei Listen zusammengefügt werden, anstatt der anderen Liste einen einzelnen Wert hinzuzufügen).
  • With: stimmt mit einigen anderen unveränderlichen Konventionen überein, hat aber nicht ganz die gleiche "Hinzufügung" zu IMO.
  • And: nicht sehr aussagekräftig.
  • Überladung des Operators für +: Ich mag das wirklich nicht sehr. Ich denke im Allgemeinen, dass Operatoren nur auf niedrigere Typen angewendet werden sollten. Ich bin jedoch bereit, mich überreden zu lassen!

Die Kriterien, die ich für die Auswahl verwende, sind:

  • Gibt den richtigen Eindruck des Ergebnisses des Methodenaufrufs (d. H. Dass es sich um die ursprüngliche Liste mit einem zusätzlichen Element handelt)
  • Macht es so klar wie möglich, dass es die bestehende Liste nicht verändert
  • Klingt vernünftig, wenn es wie im zweiten Beispiel oben verkettet ist

Bitte fordern Sie weitere Informationen an, wenn ich mich nicht klar genug ausdrücke ...

EDIT 1: Hier ist meine Begründung, warum ich Plus vor Add bevorzuge. Betrachten Sie diese beiden Codezeilen:

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

Meiner Meinung nach (und dies ist eine persönliche Sache) ist letzteres eindeutig fehlerhaft - es ist, als würde man "x + 5" schreiben. als eigenständige Aussage. Die erste Zeile scheint in Ordnung zu sein, bis Sie sich daran erinnern, dass sie unveränderlich ist. Tatsächlich ist die Art und Weise, in der der Plus-Operator seine Operanden nicht mutiert, ein weiterer Grund, warum Plus mein Favorit ist. Ohne das leichte Übel der Überladung von Operatoren gibt es immer noch die gleichen Konnotationen, einschließlich (für mich), die Operanden (oder in diesem Fall das Methodenziel) nicht zu mutieren.

EDIT 2: Gründe, warum Add nicht gefällt.

Verschiedene Antworten sind effektiv: "Gehen Sie mit Hinzufügen. Das ist, was DateTime tut, und String hat Replace Methoden usw., die die Unveränderlichkeit nicht offensichtlich machen." Ich stimme zu - hier hat Vorrang. Ich habe jedoch viele Leute gesehen, die DateTime.Add Oder String.Replace Aufgerufen haben und eine Mutation erwarten . Es gibt Unmengen von Newsgroup-Fragen (und wahrscheinlich SO= wenn ich mich umschaue)), die mit "Sie ignorieren den Rückgabewert von String.Replace; Zeichenfolgen sind unveränderlich, a neue Zeichenfolge wird zurückgegeben. "

Jetzt sollte ich die Frage etwas subtiler beantworten - der Typ ist möglicherweise nicht eine unveränderliche Liste, sondern ein anderer unveränderlicher Typ. Insbesondere arbeite ich an einem Benchmarking-Framework, bei dem Sie einer Suite Tests hinzufügen und so eine neue Suite erstellen. Es könnte offensichtlich sein, dass:

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

wird nichts erreichen, aber es wird eine Menge düsterer, wenn Sie es ändern zu:

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

Das sieht so aus, als ob es in Ordnung sein sollte. Während dies für mich den Fehler klarer macht:

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

Das bettelt nur darum:

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

Im Idealfall möchte ich, dass meinen Benutzern nicht gesagt wird, dass die Testsuite unveränderlich ist. Ich möchte, dass sie in die Grube des Erfolgs fallen. Dies ist möglicherweise nicht möglich, aber ich würde es gerne versuchen.

Ich entschuldige mich dafür, die ursprüngliche Frage zu stark vereinfacht zu haben, indem ich nur von einem unveränderlichen Listentyp spreche. Nicht alle Sammlungen sind so selbsterklärend wie ImmutableList<T> :)

224
Jon Skeet

In solchen Situationen gehe ich normalerweise mit Concat. Das bedeutet für mich normalerweise, dass ein neues Objekt erstellt wird.

var p = listA.Concat(listB);
var k = listA.Concat(item);
128
MojoFilter

Ich würde mich aus einem einfachen Grund für Cons entscheiden: Es bedeutet genau das, was Sie wollen.

  1. Ich bin ein großer Fan davon, genau zu sagen, was ich meine, besonders im Quellcode. Ein Neuling muss die Definition von Cons nur einmal nachschlagen, diese dann aber tausendmal lesen und verwenden. Ich finde, dass es auf lange Sicht besser ist, mit Systemen zu arbeiten, die den üblichen Fall vereinfachen, auch wenn die Anschaffungskosten etwas höher sind.

  2. Die Tatsache, dass es für Leute ohne FP Erfahrung "bedeutungslos" wäre, ist tatsächlich ein großer Vorteil. Wie Sie bereits betont haben, haben alle anderen Wörter, die Sie gefunden haben, bereits eine Bedeutung, und diese Bedeutung ist entweder geringfügig anders oder mehrdeutig. Ein neues Konzept sollte ein neues Wort haben (oder in diesem Fall ein altes). Es wäre mir lieber, wenn jemand die Definition von Cons nachschlagen müsste, als falsch anzunehmen, dass er weiß, was Add tut.

  3. Andere Operationen, die aus funktionalen Sprachen entlehnt wurden, behalten häufig ihren ursprünglichen Namen, ohne dass dies zu Katastrophen führen kann. Ich habe keine Push-Methode gefunden, um Synonyme für "Karte" und "Reduzieren" zu finden, die für Nicht-FP-Benutzer vertrauter sind, und ich sehe auch keinen Nutzen daraus.

(Vollständige Offenlegung: Ich bin ein LISP-Programmierer, daher weiß ich bereits, was Nachteile bedeuten.)

118
Ken

Eigentlich mag ich And, besonders auf die idiomatische Weise. Ich würde es besonders begrüßen, wenn Sie eine statische readonly-Eigenschaft für die Empty-Liste hätten und den Konstruktor möglicherweise privat machen würden, sodass Sie immer aus der leeren Liste erstellen müssen.

var list = ImmutableList<string>.Empty.And("Hello")
                                      .And("Immutable")
                                      .And("Word");
58
tvanfosson

Immer wenn ich in einem Stau mit Nomenklatur bin, stoße ich auf die Interwebs.

thesaurus.com gibt dies für "add" zurück:

Definition: sich anschließen, zunehmen; mache einen weiteren Kommentar

Synonyme: anbringen, anhängen, anhängen, aufbessern, aufbessern, steigern, aufbauen, aufladen, fortsetzen, einspielen, einspielen, fleischlich darstellen raus, aufheizen, wandern, aufsteigen, anhängen, einhängen, einbinden, aufbocken, aufpeppen, zusammenfügen, pad, parlay, huckepack, einstecken, aufschütten, antworten, hochlaufen, sagen weiter, aufschlagen, Schneeball, Suppe, beschleunigen, spitzen, verstärken, ergänzen, versüßen, anheften, taggen

Ich mag den Klang von Adjoin oder einfacher Join. Das ist was du tust, richtig? Die Methode kann auch auf das Beitreten zu anderen ImmutableList<> 's.

51
spoulson

Persönlich mag ich .With (). Wenn ich das Objekt nach dem Lesen der Dokumentation oder der Codekommentare verwenden würde, wäre klar, was es tut, und es liest sich im Quellcode in Ordnung.

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

Oder du fügst "Along" hinzu .. :)

object.AlongWith("this new item");
48
LarryF

Am Ende habe ich Add für alle meine Immutable Collections in BclExtras ausgewählt. Der Grund dafür ist, dass es sich um einen leicht vorhersehbaren Namen handelt. Ich mache mir nicht so viele Sorgen, wenn Leute Add mit einem mutierenden Add verwechseln, da dem Namen des Typs Immutable vorangestellt ist.

Für eine Weile dachte ich über Cons und andere funktionale Stilnamen nach. Schließlich habe ich sie abgezinst, weil sie bei weitem nicht so bekannt sind. Sicher, funktionierende Programmierer werden verstehen, aber sie sind nicht die Mehrheit der Benutzer.

Andere Namen: Sie erwähnten:

  • Plus: Ich bin wishy/Waschen auf diesem. Für mich ist dies keine nicht mutierende Operation mehr als Add
  • Mit: Verursacht Probleme mit VB (Wortspiel beabsichtigt)
  • Überlastung des Operators: Die Auffindbarkeit wäre ein Problem

Optionen, die ich in Betracht gezogen habe:

  • Concat: Strings sind unveränderlich und verwenden dies. Leider ist es nur sehr gut für das Hinzufügen zum Ende
  • CopyAdd: Was kopieren? Die Quelle, die Liste?
  • AddToNewList: Vielleicht eine gute für List. Aber was ist mit einer Sammlung, einem Stapel, einer Warteschlange usw.?.

Leider scheint es nicht wirklich ein Wort zu geben, das ist

  1. Auf jeden Fall eine unveränderliche Operation
  2. Für die Mehrheit der Nutzer verständlich
  3. In weniger als 4 Worten darstellbar

Noch merkwürdiger wird es, wenn Sie andere Sammlungen als List betrachten. Nehmen wir zum Beispiel Stack. Selbst Programmierer im ersten Jahr können Ihnen sagen, dass Stacks über ein Push/Pop-Methodenpaar verfügen. Wenn Sie einen ImmutableStack erstellen und ihm einen völlig anderen Namen geben, nennen wir ihn Foo/Fop. Sie haben soeben mehr Arbeit hinzugefügt, damit sie Ihre Sammlung verwenden können.

Edit: Antwort auf Plus Edit

Ich verstehe, wohin du mit Plus fährst. Ich denke ein stärkerer Fall wäre eigentlich Minus zum entfernen. Wenn ich folgendes sehen würde, würde ich mich sicherlich fragen, was in aller Welt der Programmierer dachte

list.Minus(obj);

Das größte Problem, das ich mit Plus/Minus oder einer neuen Paarung habe, ist, dass es sich wie ein Overkill anfühlt. Die Sammlung selbst hat bereits einen eindeutigen Namen, das Präfix Unveränderlich. Warum noch weiter gehen und Vokabeln hinzufügen, deren Ziel es ist, die gleiche Unterscheidung wie beim Präfix "Unveränderlich" hinzuzufügen?.

Ich kann das Argument der Anrufseite sehen. Es macht es vom Standpunkt eines einzelnen Ausdrucks klarer. Aber im Kontext der gesamten Funktion scheint es unnötig.

Edit 2

Stimmen Sie zu, dass die Leute definitiv durch String.Concat und DateTime.Add verwirrt wurden. Ich habe mehrere sehr helle Programmierer gesehen, die auf dieses Problem gestoßen sind.

Ich denke jedoch, ImmutableList ist ein anderes Argument. Es gibt nichts an String oder DateTime, das es für einen Programmierer als unveränderlich festlegt. Sie müssen einfach wissen, dass es über eine andere Quelle unveränderlich ist. Die Verwirrung ist also nicht unerwartet.

ImmutableList hat dieses Problem nicht, da der Name sein Verhalten definiert. Man könnte argumentieren, dass die Leute nicht wissen, was Unveränderlich ist, und ich denke, das gilt auch. Ich wusste es erst ungefähr im zweiten Schuljahr. Sie haben jedoch das gleiche Problem mit dem Namen, den Sie anstelle von "Hinzufügen" auswählen.

Edit 3: Was ist mit Typen wie TestSuite, die unveränderlich sind, aber kein Wort enthalten?

Ich denke, das bringt die Idee auf den Punkt, dass Sie keine neuen Methodennamen erfinden sollten. Denn es besteht eindeutig ein Bestreben, Typen unveränderlich zu machen, um Paralleloperationen zu ermöglichen. Wenn Sie sich darauf konzentrieren, den Namen von Methoden für Sammlungen zu ändern, sind die Namen der mutierenden Methoden für jeden Typ, den Sie verwenden, unveränderlich.

Ich denke, es wäre eine wertvollere Anstrengung, sich stattdessen darauf zu konzentrieren, Typen als unveränderlich identifizierbar zu machen. Auf diese Weise können Sie das Problem lösen, ohne jedes Mutationsmethodenmuster zu überdenken.

Wie können Sie nun TestSuite als unveränderlich identifizieren? In der heutigen Umgebung gibt es meiner Meinung nach einige Möglichkeiten

  1. Präfix mit Immutable: ImmutableTestSuite
  2. Fügen Sie ein Attribut hinzu, das den Grad der Unveränderlichkeit beschreibt. Dies ist sicherlich weniger auffindbar
  3. Sonst nicht viel.

Ich vermute/hoffe, dass Entwicklungstools anfangen werden, dieses Problem zu lösen, indem es einfach gemacht wird, unveränderliche Typen einfach anhand des Sehens zu identifizieren (andere Farbe, stärkere Schriftart usw.). Aber ich denke, das ist die Antwort, wenn man alle Methodennamen ändert.

33
JaredPar

Ich denke, dies ist eine der seltenen Situationen, in denen es akzeptabel ist, den Operator + Zu überladen. In der mathematischen Terminologie wissen wir, dass + Etwas nicht an das Ende von etwas anderem anfügt. Es werden immer zwei Werte miteinander kombiniert und ein neuer resultierender Wert zurückgegeben.

Zum Beispiel ist es intuitiv offensichtlich, dass, wenn Sie sagen

x = 2 + 2;

der resultierende Wert von x ist 4, nicht 22.

Ähnlich,

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

sollte klar machen, was jede Variable halten wird. Es sollte klar sein, dass list2 Nicht geändert in der letzten Zeile ist, sondern dass list3 Das Ergebnis des Anhängens von "Word" an list2.

Ansonsten würde ich nur die Funktion Plus () benennen.

27
Bill the Lizard

Um so klar wie möglich zu sein, sollten Sie das Wort CopyAndAdd oder etwas Ähnliches verwenden.

22
Michael Myers

Ich würde es Extend () oder vielleicht ExtendWith () nennen, wenn Sie wirklich wortreich sind.

Erweitern bedeutet, etwas zu etwas anderem hinzuzufügen, ohne es zu ändern. Ich denke, dies ist eine sehr relevante Terminologie in C #, da dies dem Konzept der Erweiterungsmethoden ähnelt - sie "fügen" einer Klasse eine neue Methode hinzu, ohne die Klasse selbst zu "berühren".

Andernfalls, wenn Sie wirklich betonen möchten, dass Sie das ursprüngliche Objekt überhaupt nicht ändern, erscheint es mir unvermeidlich, ein Präfix wie Get zu verwenden.

21
Tamas Czinege

Ich mag mmyers Vorschlag von CopyAndAdd. Passend zu einem "Mutation" -Thema könnten Sie vielleicht mit Bud (asexuelle Reproduktion), Grow, Replicate oder Evolve? =)

EDIT: Um mit meinem genetischen Thema fortzufahren, wie wäre es mit Procreate, was bedeutet, dass ein neues Objekt erstellt wird, das auf dem vorherigen basiert, aber mit etwas Neuem.

18
gnovice

Hinzugefügt (), Angefügt ()

Ich verwende die Vergangenheitsform gerne für Operationen an unveränderlichen Objekten. Es vermittelt die Idee, dass Sie das ursprüngliche Objekt nicht ändern, und es ist leicht zu erkennen, wenn Sie es sehen.

Da es sich bei mutierenden Methodennamen häufig um Präsensverben handelt, gilt dies auch für die meisten Fälle, in denen der Name einer unveränderlichen Methode benötigt wird. Zum Beispiel hat ein unveränderlicher Stapel die Methoden "pushed" und "popped".

16
Craig Gidney

Dies ist wahrscheinlich eine Strecke, aber in Ruby) gibt es eine häufig verwendete Notation für die Unterscheidung: add mutiert nicht; add! mutiert. Wenn dies ein allgegenwärtiges Problem in Ihrem Projekt ist, können Sie dies auch tun (nicht unbedingt mit nicht-alphabetischen Zeichen, sondern konsequent unter Verwendung einer Notation, um mutierende/nicht-mutierende Methoden anzugeben).

14
ykaganovich

Join scheint angemessen.

13
ykaganovich

Vielleicht rührt die Verwirrung von der Tatsache her, dass Sie zwei Operationen in einer wollen. Warum sie nicht trennen? DSL-Stil:

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

Copy würde ein Zwischenobjekt zurückgeben, das eine veränderbare Kopie der ursprünglichen Liste ist. With würde eine neue unveränderliche Liste zurückgeben.

Aktualisieren:

Es ist jedoch kein guter Ansatz, eine veränderbare Zwischenkollektion zu haben. Das Zwischenobjekt sollte in der Operation Copy enthalten sein:

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

Jetzt übernimmt die Operation Copy einen Delegaten, der eine veränderbare Liste erhält, damit er das Kopierergebnis steuern kann. Es kann viel mehr als nur ein Element anhängen, z. B. Elemente entfernen oder die Liste sortieren. Es kann auch im Konstruktor ImmutableList verwendet werden, um die Anfangsliste ohne zwischengeschaltete unveränderliche Listen zusammenzustellen.

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);
}

Jetzt gibt es keine Möglichkeit einer Fehlinterpretation durch die Benutzer, sie werden natürlich in die grube des erfolgs fallen.

Noch ein Update:

Wenn Ihnen die Erwähnung der veränderlichen Liste auch jetzt noch nicht gefällt, können Sie ein Spezifikationsobjekt entwerfen, das angeben oder Skript angibt, wie der Kopiervorgang ausgeführt wird verwandelt seine Liste. Die Verwendung wird die gleiche sein:

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!"));

Jetzt können Sie mit den Regelnamen kreativ sein und nur die Funktionen verfügbar machen, die von Copy unterstützt werden sollen, nicht die gesamten Funktionen eines IList.

Für die Verkettung können Sie einen vernünftigen Konstruktor erstellen (der natürlich keine Verkettung verwendet):

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

...

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

Oder verwenden Sie denselben Delegaten in einem anderen Konstruktor:

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

Dies setzt voraus, dass die rules.Append Methode gibt this zurück.

So würde es mit Ihrem neuesten Beispiel aussehen:

var suite = new TestSuite<string, int>(x => x.Length);
var otherSuite = suite.Copy(rules => 
  rules
    .Append(x => Int32.Parse(x))
    .Append(x => x.GetHashCode())
);
13
Jordão

Ein paar zufällige Gedanken:

  • UnveränderlichAdd ()
  • Anhängen ()
  • ImmutableList <T> (ImmutableList <T> originalList, T newItem) Konstruktor
11
Chris Shaffer

DateTime in C # verwendet Add. Warum also nicht den gleichen Namen verwenden? Solange die Benutzer Ihrer Klasse wissen, dass die Klasse unveränderlich ist.

10
Tundey

Zunächst ein interessanter Ausgangspunkt: http://en.wikipedia.org/wiki/Naming_conventions_ (programming) ... Überprüfen Sie insbesondere die Links "See Also" unten.

Ich bin entweder für Plus oder Und, praktisch gleichermaßen.

Plus und Und basieren beide auf Etymologie. Insofern bedeuten beide mathematische Operationen; beide ergeben einen Ausdruck, der natürlich als Ausdrücke gelesen wird, die sich in einen Wert auflösen können, der zu der Methode mit einem Rückgabewert passt. And weist eine zusätzliche logische Konnotation auf, aber beide Wörter gelten intuitiv für Listen. Add bezeichnet eine Aktion, die für ein Objekt ausgeführt wird und mit der unveränderlichen Semantik der Methode in Konflikt steht.

Beide sind kurz, was angesichts der Primitivität der Operation besonders wichtig ist. Einfache, häufig ausgeführte Operationen verdienen kürzere Namen.

Die unveränderliche Semantik auszudrücken, ist etwas, was ich lieber über den Kontext tue. Das heißt, ich würde eher einfach implizieren, dass dieser gesamte Codeblock ein funktionales Gefühl hat; Angenommen, alles ist unveränderlich. Das könnte jedoch nur ich sein. Ich bevorzuge, dass Unveränderlichkeit die Regel ist. Wenn es erledigt ist, ist es viel am selben Ort erledigt. Mutabilität ist die Ausnahme.

9
Paul Brinkley

Ich glaube nicht, dass die englische Sprache Sie auf unverwechselbare Weise unveränderlich machen lässt, wenn Sie ein Verb verwenden, das dasselbe wie "Hinzufügen" bedeutet. "Plus" macht es fast, aber die Leute können immer noch den Fehler machen.

Der einzige Weg, um zu verhindern, dass Ihre Benutzer das Objekt für etwas Veränderliches halten, besteht darin, es explizit zu machen, entweder durch den Namen des Objekts selbst oder durch den Namen der Methode (wie bei den ausführlichen Optionen wie "GetCopyWith" oder "GetCopyWith") "CopyAndAdd").

Also gehen Sie einfach mit Ihrem Favoriten "Plus".

9
Adam Bellaire

Ich denke, der Schlüssel, an den Sie herankommen wollen, ist die Nichtpermutation, also vielleicht etwas mit einem generativen Wort, so etwas wie CopyWith () oder InstancePlus ().

9
chaos

Wie wäre es mit Chain () oder Attach ()?

8
Webjedi

Ich bevorzuge Plus (und Minus). Sie sind leicht verständlich und lassen sich direkt auf Operationen mit bekannten unveränderlichen Typen (den Zahlen) abbilden. 2 + 2 ändert den Wert von 2 nicht, sondern gibt einen neuen, ebenfalls unveränderlichen Wert zurück.

Einige andere Möglichkeiten:

Spleißen()

Pfropfen()

Accrete ()

7
Wedge

Anscheinend bin ich die erste Obj-C/Cocoa Person, die diese Frage beantwortet.

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

Damit werden Sie keine Code-Golf-Spiele gewinnen.

7
kubi

Wie wäre es mit mate, mateWith oder coitus für diejenigen, die bleiben. In Bezug auf die Fortpflanzung gelten Säugetiere im Allgemeinen als unveränderlich.

Wir werfen nion auch da draußen. Aus SQL ausgeliehen.

6
jason saldo

Ich denke, dass Plus() und Minus() oder alternativ Including(), Excluding() angemessen sind bei impliziert unveränderlichem Verhalten .

Keine Namenswahl wird es jedoch jedem klar machen, weshalb ich persönlich der Meinung bin, dass ein guter XML-Dokumentenkommentar hier einen sehr langen Weg gehen würde. VS wirft diese direkt in Ihr Gesicht, wenn Sie Code in das IDE - sie sind schwer zu ignorieren.

5
LBushkin

Unter http://thesaurus.reference.com/browse/add und http://thesaurus.reference.com/browse/plus fand ich Gain und Affix , aber ich bin nicht sicher, wie sehr sie Nicht-Mutation implizieren.

5
Sam Hasler

Ich denke, "Hinzufügen" oder "Plus" klingt gut. Der Name der Liste selbst sollte ausreichen, um die Unveränderlichkeit der Liste zu verdeutlichen.

5
David Morton

Vielleicht gibt es einige Wörter, die mich mehr daran erinnern, eine Kopie zu erstellen und Dinge hinzuzufügen, anstatt die Instanz zu mutieren (wie "Verketten"). Aber ich denke, eine gewisse Symmetrie für diese Worte für andere Taten wäre auch gut zu haben. Ich kenne kein ähnliches Wort für "Entfernen" wie "Verketten". "Plus" klingt für mich etwas seltsam. Ich würde nicht erwarten, dass es in einem nicht numerischen Kontext verwendet wird. Aber das könnte auch von meinem nicht englischen Hintergrund kommen.

Vielleicht würde ich dieses Schema verwenden

AddToCopy
RemoveFromCopy
InsertIntoCopy

Diese haben jedoch ihre eigenen Probleme, wenn ich darüber nachdenke. Man könnte denken, sie entfernen etwas oder fügen etwas zu einem Argument hinzu. Ich bin mir überhaupt nicht sicher. Ich denke, diese Worte spielen auch beim Verketten keine Rolle. Zum Tippen zu wortreich.

Vielleicht würde ich einfach "Hinzufügen" und Freunde auch verwenden. Mir gefällt, wie es in der Mathematik verwendet wird

Add 1 to 2 and you get 3

Na klar, eine 2 bleibt eine 2 und du bekommst eine neue Zahl. Hier geht es um zwei Zahlen und nicht um eine Liste und ein Element, aber ich denke, es hat eine gewisse Analogie. Meiner Meinung nach bedeutet add nicht unbedingt, dass Sie etwas mutieren. Ich verstehe sicherlich, dass eine einsame Anweisung, die nur ein add enthält und das zurückgegebene neue Objekt nicht verwendet, nicht fehlerhaft aussieht. Aber ich habe jetzt auch einige Zeit darüber nachgedacht, einen anderen Namen als "add" zu verwenden, aber ich kann mir keinen anderen Namen einfallen lassen, ohne dass ich darüber nachdenke es geht um "weil sein Name sich von dem unterscheidet, was ich als" add "erwarten würde. Nur ein paar seltsame Gedanken von litb, nicht sicher, ob es überhaupt Sinn macht :)

list.CopyWith(element)

Wie auch Smalltalk :)

Und auch list.copyWithout(element), das alle Vorkommen eines Elements entfernt. Dies ist am nützlichsten, wenn es als list.copyWithout(null) verwendet wird, um nicht gesetzte Elemente zu entfernen.

4
akuhn

Append - Beachten Sie, dass die Namen der System.String Methoden schlagen vor, dass sie die Instanz mutieren, aber sie tun es nicht.

Oder ich mag AfterAppending:

void test()
{
  Bar bar = new Bar();
  List list = bar.AfterAppending("foo");
}
4
ChrisW

Ich persönlich mag unite(), als wenn Sie Objekte vereinen, bewahren Sie dennoch ihre Individualität, aber die Vereinigung von ihnen ist eine separate neue Einheit. Union ist ähnlich wie vorgeschlagen, ist aber in der Mengenlehre bereits gut definiert, und unite ist ausführlicher und sagt mir, dass ich nach der Methode eine neue Fähigkeit habe. Ich weiß, dass es spät ist, aber ich konnte den Vorschlag auf der Liste nicht finden. Außerdem erinnert mich das Wort an die Tage der alten und vereinigenden Menschen, um in den Krieg zu ziehen ... hehe

3

Ich würde mich für Add entscheiden, weil ich den Vorteil eines besseren Namens sehe, aber das Problem wäre, für jede andere unveränderliche Operation andere Namen zu finden, die die Klasse möglicherweise ziemlich ungewohnt machen, wenn das Sinn ergibt.

3
Joan Venge

Vielleicht ist eine statische Methode oder ein Operator (der statisch ist) am besten. Dies würde den Instanzen die Verantwortung abnehmen, und die Benutzer werden sofort wissen, dass der Vorgang keiner der Instanzen angehört. Es ist besonders wichtig, KEINE Erweiterungsmethoden zu verwenden, da ihre Ähnlichkeit mit Instanzmethoden bei Verwendung den Zweck zunichte macht.

Die statische Methode könnte Join heißen:

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!");

Aber ich würde es vorziehen, wenn C # hier klassenfreie Funktionen hätte. Oder zumindest so etwas wie die statische Importfunktion von Java.

Der Operator könnte + Sein:

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

Aber ich könnte lieber etwas anderes wie <<, :: Oder . Verwenden, was in C # nicht möglich ist.

Außerdem sehen statische Elemente funktionaler aus und ich denke, sie eignen sich besser für diese unveränderliche Sichtweise.

3
Jordão

Wie wäre es mit cloneWith?

Gründe:
1. Bei den einzelnen vorgeschlagenen Wortnamen würde ich nicht genau wissen, was sie tun, bis ich die Dokumentation überprüft habe.
2. Für die bisher vorgeschlagenen zusammengesetzten Namen mag ich cloneWith besser. Ich würde genau wissen, was ich mit diesem Methodennamen bekommen habe, es ist relativ kurz, es ist leicht zu merken und es fühlt sich einfach richtig an :)
3. Mit der modernen Code-Vervollständigung in den meisten Programmiertools ist es einfacher als je zuvor, mit längeren Namen zu arbeiten.

Obwohl oftmals Prägnanz zur Klarheit beiträgt, sollten Sie Klarheit über Prägnanz nehmen, wenn Sie sich entscheiden müssen ...

In Aktion:

var empty = new ImmutableList<string>();
var list1 = empty.cloneWith("Hello");
var list2 = list1.cloneWith("immutable");
var list3 = list2.cloneWith("Word");
2
Briguy37

Ich würde mit list.NewList("Word") gehen, weil es beschreibt, was Sie tun (Erstellen einer neuen Liste).

Ich muss zustimmen, dass dies nicht bedeutet, dass das Argument am Ende der Liste angefügt wird, aber ich persönlich gehöre zum kurzgefasstes, wenn mögliches Lager, also würde ich list.NewList("Word") bevorzugen. über list.NewListAfterAppend("Word").

2
Pacerier

Der Name WithAdded liest sich gut und ist meiner Meinung nach besser als Added, was als Adjektiv gelesen werden kann.

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

Oder für eine etwas ausführlichere Version:

var list2 = list1.WithAddedElement("immutable");
2

Ich bin ein bisschen zu spät zur Party, aber ich habe keine Antwort gefunden, die darauf hindeutet, es überhaupt nicht zu tun! Lass es unveränderlich bleiben. Jede Methode, die Sie verwenden, kann zu Missbrauch führen, wenn sie in eine Schleife gerät, was schließlich passieren wird. Stattdessen würde ich empfehlen, stattdessen einen Builder zu verwenden.

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

Im Fall einer ImmutableList wäre Ihr Builder höchstwahrscheinlich nur eine Liste.

Ich denke, es läuft alles auf ... Sie möchten wirklich auf einfache Weise Ihrer unveränderlichen Sammlung nur ein einziges Element hinzufügen? Wenn dies häufig vorkommt, möchten Sie wahrscheinlich kein unveränderliches Objekt verwenden (Sie können build() jederzeit aufrufen, wenn Sie einen Schnappschuss des Objekts in seinem aktuellen Zustand senden möchten ...) Wenn Es kommt nicht häufig vor, dass ein Builder als Voraussetzung dafür vorhanden ist. Dies wäre kein wesentliches Hindernis, insbesondere wenn dokumentiert wäre, dass Sie sie auf diese Weise erstellen möchten.

@supercat - Stellen Sie sich das folgende Szenario vor, das Sie beschreiben:

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?
2
corsiKa

2 Vorschläge:

Eine "freie" Funktion:

Foo f = new Foo(whatever);
Foo fPlusSomething = Foo.Concat(f, something);

Eine Konstruktorüberladung (in gewisser Weise eine Variation des Themas "freie Funktion"):

Foo f = new Foo(whatever);
Foo fPlusSomething = new Foo(f, something);
2
Éric Malenfant

Ich persönlich würde mit AddVoid gehen oder umgekehrt von VoidAdd

1
Woot4Moo

Wenn Sie ein funktionaler Programmierer sind, hat dies ein paar Namen:

(++)

ausgesprochen "anhängen". Oder es könnte concat sein, abhängig von Ihrem Typ:

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

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

Oder du meinst vielleicht (:), AKA cons:

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

wenn Sie Dinge an die erste Stelle der Liste setzen, snoc, wenn sie am Ende stehen.

Zumindest fordern wir seit 20 Jahren das Anhängen von Dingen an Listen in Haskell-Land.


Beachten Sie, dass dies keine Arithmetik ist (+), da es monoidal ist, kein Ring.

1
Don Stewart

copyWithSuffix: wäre ein benutzerdefinierter Methodenname in ähnlicher Weise wie die Objective-C-Methode zum Kopieren unveränderlicher Zeichenfolgen stringByAppendingString:.

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

Suffix teilt die Addition mit und Copy verdeutlicht die Unveränderlichkeit. Fühlen Sie sich frei, Suffix durch etwas Logischeres für die Art der Testsuite zu ersetzen, die es tatsächlich ist (vielleicht fügen Sie diese nicht zu einer großen internen Zeichenfolge hinzu, Sie könnten Testfallnamen/-parameter für alle bereitstellen Ich kenne).

1
darvids0n

1) Fragenanalyse
Zusammenfassung der Frage kann sein:
Von einem unveränderlichen ... erhalten Sie einen neuen unveränderlichen, der sich jedoch vom ursprünglichen unterscheidet.
In diesem aktuellen Fragenkontext:
Erhalte aus einer unveränderlichen Liste eine neue unveränderliche Liste, die am Ende zusätzlich einen Unterschied von einem neuen Element aufweist.

Können Sie ein effektives "Verb" ("Methode" in der Programmiersprache) angeben, das die Aktion ohne Verwendung des einfachen "Add" -Verbs präzise ausdrückt?.

2) Angebotsanalyse
Erstes Konzept: Unveränderlich geben Sie eine ähnliche unveränderliche,
>> "copy" verb drückt die Erhaltung in "Inhalt" aus, aber weniger für ihn definierte Einschränkungen (unveränderlich) )
>> "Klon" verb drücken konservativ in "Inhalt" aus, aber auch für seine definierten Einschränkungen.
>> "twin" verb ähnelt clone, ist aber in der Software nicht üblich, ist aber kurz und klingt gut.

Zweites Konzept: Das Ergebnis gibt etwas anderes als das Original
>> "add" drücke ein Aktion aus, um den Unterschied zwischen dem ursprünglichen und dem neuen Objekt zu machen, aber per definitionem handeln (mutieren) wir nicht unveränderlich.
>> "plus" drücken die Tatsache aus, dass das Verbergebnis vergrößert wird, ohne das ursprüngliche Objekt zu stören ... "Adverb" -Ansatz ist "unveränderlicher" freundlicher
>> "mit" wie zuvor drückt es die Tatsache aus, dass "Verb" etwas mehr bewirkt, aber möglicherweise zweideutig ist, was es mehr bewirkt. Kann auch die Tatsache ausdrücken, dass der "Verbparameter" das "Mehr" des "Verbs" ist

) Antworten
Mit Verb "clone"
>> AugmentClone
>> growClone
>> extendClone
mit mit"
>> cloneWith
>> augmentCloneWith
>> growCloneWith
>> extendCloneWith

Mit Verb "twin"
>> augmentTwin
>> growTwin
>> extendTwin
mit mit"
>> twinWith
>> augmentTwinWith
>> growTwinWith
>> extendTwinWith

1
Emmanuel Devaux

Jeder Name, der impliziert, dass ein Objekt desselben Typs zurückgegeben wird, sollte in Ordnung sein. Plus ist ein guter Name dafür, als ob Sie plus zwei Objekte erwarten, dass das Ergebnis zurückgegeben wird.

Plus klingt jedoch nicht nach dem richtigen Namen für diese Instanz, da Sie einen Test in eine Testsuite einfügen.

GetWith () klingt für mich nach einer Option. Oder immer GetTypeWith (), wobei type offensichtlich der Typ ist, den Sie verwenden. Also zum Beispiel:

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

// OR

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

Das Get impliziert, dass Sie die Liste erhalten, die bereits enthalten ist, und das With impliziert, dass Sie ein anderes Objekt zusammen mit diesem Objekt wünschen. CopyWith () würde auch diese Kriterien erfüllen.

Das unmittelbare Problem, das ich bei GetWith sehe, ist, dass es nicht leicht zu erraten ist. Ein Entwickler möchte eine Suite hinzufügen, nicht die aktuelle Suite. Ich tippe sofort .Add und hoffe, dass die Intelligenz etwas zeigt, das den Erwartungen sehr nahe kommt.

1
Josh Smeaton

Während die Methode korrekt benannt wird, kann die Wahrscheinlichkeit eines Missbrauchs verringert werden. Wenn es ein Sprachkonstrukt gab, das dem Compiler mitteilte: "Diese Methode gibt nur ein neues Objekt zurück, es sollte verwendet werden, oder der Methodenaufruf ist bedeutungslos", und dann könnte der Compiler Beschweren Sie sich mit einem Fehler/einer Warnung, wenn jemand die Methode in einer falschen Konfiguration verwendet.

Ich habe ein Feature Request ausgefüllt. Wenn Sie damit einverstanden sind, können Sie gerne abstimmen.

1
Alireza

Als C++ - Programmierer und Fan der STL habe ich add_copy. (Dies würde auch vorschlagen, remove_copy, replace_copy und so weiter)

1
KitsuneYMG

Dies scheint darauf hinauszulaufen, ein Wort zu finden, das ausdrückt, dass das Objekt nicht geändert wurde. Außerdem wird das geklonte Element, das als Parameter übergeben wurde, am Ende der geklonten Liste hinzugefügt. Standardnamen wie add und clone werden es niemals verdecken. Vielleicht clone_and_append, Was auch ziemlich vieldeutig ist, da der Teil append bedeuten könnte, dass der Parameter an die ursprüngliche Liste angehängt wird. Es sollte also wahrscheinlich so etwas wie clone_and_append_to_clone Oder besser noch append_to_clone Sein, obwohl dies nicht wirklich impliziert, dass der Klon durch diese Methode zurückgegeben wird, sondern dass der Klon bereits als existiert Teil der Originalliste.

Berücksichtigen Sie daher die folgenden Aspekte, um einen Namen zu finden, der keine Änderung der ursprünglichen Liste impliziert, und schlagen Sie vor, dass eine neue Liste erstellt wird:

  1. Offshoot - var list1 = list.Offshoot("tail") - im engeren Sinne bezieht sich offshoot hier auf das neue Element und nicht die gesamte neue Liste. Ein weiterer offensichtlicher Nachteil ist, dass es sich nicht um eine Aktion handelt. Der korrektere Name lautet list.CreateOffshoot. Ich finde jedoch, dass es einen klaren Hinweis darauf gibt, dass die neue Liste die ursprüngliche Liste enthält und das neue Element am Ende der Liste steht.
  2. Spawn - var list1 = list.Spawn("tail") - ähnlich wie beim vorherigen. Der Vorteil ist, dass es sich um eine Aktion handelt, aber es gibt eine schwächere Implikation, dass die neue Liste die ursprüngliche Liste enthält.
  3. BranchOff - var list1 = list.BranchOff("tail") - eine Aktion, die vorschlägt, dass die ursprüngliche Liste geklont wird. Eine mögliche Mehrdeutigkeit besteht darin, dass nicht klar ist, wie das Parameterelement verwendet wird.
1
Nick

Persönlich würde ich die Methode Clone aufrufen und den Parameter AdditionalValue aufrufen, da dies im Wesentlichen das ist, was es zu tun scheint und wäre leicht verständlich zB.

var empty = new ImmutableList<string>(); 
var list1 = empty.Clone("Hello"); 
var list2 = list1.Clone("immutable"); 
var list3 = list2.Clone("Word");
0
James

Wie wäre es mit "Stick" oder "Stick To", es klebt ein Element am Ende.

Oder "Attatch" oder "Attach To".

0
Alex Baranosky

Wie wäre es, eine Wrapper-Klasse mit einer Augment (oder AugmentWith) -Methode zu erstellen?

0
user1342582

Das Problem mit Methoden wie String.Replace ist, dass der Benutzer fälschlicherweise annehmen kann, dass eine Mutation stattfindet, weil er den Rückgabewert ignorieren kann. Verwenden Sie also einen out -Parameter für den "Rückgabewert". Der Benutzer kann nicht ignorieren dass:

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) {
    // ...
  }
}

Verwendung:

var list = new ImmutableList<string>("Hello", "Immutable");
ImmutableList<string> newList;
list.Add(out newList, "World");
0
Jordão

Ich würde mit Operatorüberladung gehen +. Der Grund dafür ist, dass dies in Python - .append() für eine Liste so funktioniert, dass die Liste mutiert, während + Für eine andere Liste eine neue Liste erstellt . + Impliziert auch definitiv keine Mutation. Ich denke, deshalb magst du .Plus() so sehr. Wenn du also keine Operatorüberladung willst, kannst du mit .Plus().

0
Claudiu

Ich würde es ToInclude nennen

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

idiomatisch (?)

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

Funktioniert auch für den von Ihnen genannten Fall.

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

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

Wie bereits erwähnt, versuchen Sie, zwei Dinge gleichzeitig zu tun und die Mikrooptimierung nur für diesen Zweck durchzuführen. Wenn außerhalb der ursprünglichen Sammlungsdefinition kopiert wird, sind Namen wie "Hinzufügen" und "Anhängen" nur verwirrend.

"CloneAppend" ist das, was ich in dieser Situation verwenden könnte. Etwas sagt mir, dass ich nicht in dieser Situation sein würde. Ich glaube, dass Sie bald andere ähnliche Operationen wie "CloneFirstN" oder "CloneRemoveLast" benötigen werden. Und bald werden Sie feststellen, dass es viel besser ist, die Klon-/Kopiermethode zu verketten, anzufügen/zu entfernen und die Sammlung dann wieder in unveränderlichen Code zu konvertieren, selbst wenn eine zusätzliche Codezeile erforderlich ist.

0
Andrei R

Ich weiß, dass dies ein scheinbar totes Pferd schlägt, aber ich denke, Sie nähern sich dem auf seltsame Weise (daher die Schwierigkeit der Namensgebung). Wenn ich ein unveränderliches Objekt habe, erwarte ich nicht oft, dass das Objekt Funktionen hat, die eine Veränderbarkeit implizieren (wie Add oder AddAll). Ich weiß, dass String & DateTime dies tun, aber selbst ich habe vergessen, die Ergebnisse von DateTime/String-Funktionen zu verwenden, sodass ich diese Fallstricke nach Möglichkeit vermeiden würde.

Wenn ich Sie wäre, würde ich dem Builder-Muster folgen, ähnlich dem, was Guava verwendet. Siehe nveränderliche Sammlungen in Guave . Grundsätzlich besteht das Konzept darin, dass Sie das unveränderliche Objekt mit allem konstruieren, was es jemals enthalten wird. Wenn Sie ein neues unveränderliches Objekt erstellen möchten, müssen Sie einen neuen Builder verwenden.

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

Sie können den Builder erweitern, um eine Vielzahl von Änderungen an der Testsuite zuzulassen (unter Verwendung von Standard-Listenbenennungskonventionen wie Hinzufügen/Entfernen, wenn Sie dies wünschen), bevor der Benutzer den Build aufruft.

0

Ich würde einen Konstruktor verwenden.

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

f1 enthält "eins". f2 enthält "eins", "zwei". f3 enthält "eins", "zwei", "drei".

0
Skip Head

Für diese Art von Funktionen verwende ich normalerweise das Verb in der zweiten Form, in diesem Fall Added.

Diese Konvention wird von Qt verwendet, zum Beispiel QVector2D::normalized gibt einen normalisierten Vektor zurück, während QVector2D::normalize normalisiert einen Vektor.

Auf die gleiche Weise würde Added das Objekt mit einem neu hinzugefügten Element zurückgeben.

0
peoro

Da der Typname ImmutableList ist und somit angibt, dass er tatsächlich unveränderlich ist, denke ich, dass .Add () in Ordnung ist. Wenn Sie jedoch wirklich auf etwas anderes bestehen, kann es sein, dass Sie .AddEx () verwenden, wobei "Ex" "Erweitert" bedeutet und impliziert, dass der Benutzer vor der Verwendung bestimmen sollte, was dieses Ex ist (indem er Dokumente liest). Ich mag auch den Vorschlag von Plus () und GetCopyWith ()

0
shsteimer

Wie wäre es mit einer Erweiterungsmethode? Sie könnten es in diesem Fall Join nennen. Als Erweiterungsmethode sollten Benutzer wissen, dass es sich um eine statische Methode handelt, und sie sollten daher eine kleine Pause einlegen und sie dazu ermutigen, sich den Rückgabewert anzusehen. Gleichzeitig haben Sie die Benutzerfreundlichkeit einer "Instanz" -Methode.

public static ImmutableList<T> Join(this ImmutableList<T> body, T tail)
{
    // add robust error checking in case either is null...
    return new ImmutableList<T>(body, tail);
}

und dann später ...

var list = new ImmutableList<string>().Join("Hello")
                                      .Join("Extensible")
                                      .Join("World");

Ich kenne das akzeptierte Verhalten beim Posten von Mehrfachantworten nicht ganz, aber dies ist eine interessante Frage, da ich denke, dass die Nomenklatur ein entscheidender Schritt im Design ist und mein Gehirn darüber nachdenkt.

0
Erich Mirabal

C # -ish Pseudocode folgt:

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

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

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

Man könnte also so etwas nennen:

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()));

Etc....

0
orj

Sehr spät zum Spiel, aber wie wäre es mit Freeze. In WPF hat die Verwendung von Freeze und IsFrozen Vorrang, um zu testen, ob ein Objekt veränderbar ist. Zugegeben, dies verzerrt die Bedeutung ein wenig, da Freeze() normalerweise dazu gedacht ist, das aktuelle Objekt unveränderlich zu machen. Wenn es jedoch einen Parameter enthält, können Sie erkennen, dass Sie etwas erhalten, das unveränderlich ist .

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

Grundsätzlich:

  1. Es ist ein Wort
  2. Die Konnotation dreht sich um Unveränderlichkeit.
  3. Priorität in WPF für "ähnliche" Syntax.
0
Erich Mirabal

Ich würde mit "CreateNewListWithAdditionalItems" gehen

Ich habe nichts gegen lange Namen, aber dieser sagt Ihnen, was es tatsächlich tun wird. Außerdem würde ich eine Ausnahme auslösen, wenn Sie Add oder eine andere Änderungsmethode verwenden.

0
Heiko Hatzfeld

Eine sehr späte Antwort, aber ich wollte meine zwei Cent hinzufügen: Ich denke, der Punkt hier könnte die Zeitform mehr als das Verb selbst sein:

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

Das Partizip ändert meiner Meinung nach die Bedeutung: Wir fügen nichts zu myList hinzu, sondern geben das Ergebnis der Operation zurück.

0
Pablo Lozano

Ich komme ein bisschen spät hier an, wie wäre es mit NewWith?

0
Benjol

Persönlich würde ich mich für Pad (..) entscheiden, wenn Sie einen fließenden Stil bevorzugen, auch mit einer Erweiterungsmethode von AndWith (..)

var list = new ImmutableList<string>().Pad("Hello")
                                      .AndWith("immutable")
                                      .AndWith("Word");
0
Alex Norcliffe

Ausleihen bei C, wie wäre es mit Concat

0
k rey

Ich mag und (). Ich denke, es hat das geringste Mehrdeutigkeitspotential. Der einzige Konflikt, an den ich denken kann, ist ein logisches Und, ich sehe kein Problem mit einem C # -Entwickler, und selbst für VB Ich denke, dass der Kontext es unwahrscheinlich macht, ein Problem zu verursachen und jedes Problem wird zur Kompilierungszeit schnell behoben. Es funktioniert auch gut in Englisch "Tun Sie etwas mit Diesem Und Diesem" oder "Setzen Sie Diesem Und Das in die Box".

Ich denke . Mit () ist OK. Mein Anliegen ist, dass es ein bisschen wie eine linq Where <> -Methode aussieht, besonders wenn es ein Lambda als Argument gibt. Das Englisch in meinem Kopf ist auch weniger klar, besonders "Tu was mit denen".

Ich mag nicht .Plus (). Ich kann es nicht als Synonym für Hinzufügen umgehen: plus = Pluszeichen = + = hinzufügen.

0
codybartfast

Ich denke also, eine Methode namens "ImmutableAdd ()" ist zu einfach?

0
Alex Baranosky

.Trail impliziert, dass ein sehr starkes Verständnis der Liste nicht geändert wurde. Dieses Objekt befindet sich hinter der Liste und wurde dieser nicht hinzugefügt.

var list = new ImmutableList<string>().Trail("Hello");
                                      .Trail("immutable");
                                      .Trail("Word");
0
Chris Marisic

"Ersetzen"? Es wird nicht zur Liste hinzugefügt, sondern durch eine neue Liste ersetzt.

0
Paul Tomblin

Ich würde mich für das einfache Add () entscheiden. Eine Alternative wäre Append (), wenn Sie vermitteln möchten, dass dies wirklich eine Erfassungsoperation ist.

Zusätzlich zu der expliziten Methode würde ich immer noch vorschlagen, das überladene + operatr zu implementieren. Es ist eine bekannte Operation. Jeder weiß, dass String unveränderlich ist, aber jeder verwendet das '+', um neue Instanzen davon zu erstellen.

0
Franci Penov

"hinzufügen()"

Die Tatsache, dass eine neue Liste zurückgegeben wird, spielt keine Rolle. Dies ist ein Implementierungsdetail, das durch die Signatur aufgedeckt wird. Die Hauptaktion, die die Methode ausführt, ist das "Hinzufügen" eines neuen Elements zu einer Liste. Wie oder was es deos oder gibt, sollte nicht Teil des Methodennamens sein. Wenn eine Methode synchronisiert wurde, würde sich dies auf den Methodennamen auswirken - "synchronizedAdd ()" ??? - natürlich nicht.

Klassen wie String, die dem mutatorischen Muster folgen, haben immer noch sehr einfache Methodennamen - keine sind zusammengesetzte Wörter.

0
mP.

Da diese Frage nun im Grunde genommen ein Thesaurus ist: Wie wäre es mit .Bring(). Wie in, gib mir diese Liste und bring dieses Element mit?

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

Es rollt mir nicht die Zunge runter, aber es bedeutet es, für mich.

Tatsächlich könnte AndBring() sogar noch besser sein.

0
quodlibetor

Wie wäre es mit "Augment"?

Es ist ein anderes Wort als Hinzufügen, aber es ist ein enges Synonym.

0
nsayer

Ein weiterer Punkt zugunsten von Plus ist das neue, meist unveränderliche Java-Zeit-API , mit dem plus() beispielsweise zu Instant s.

0
serv-inc

list.copyAndAppend (elt)

Wie klingt das?)

0
Bubba88