N'est-ce pas pour l'inférence de type, on pouvait "prendre le meilleur des deux mondes" en mettant en œuvre non seulement un immuable FluentThing
classe définie dans l'API, mais une autre, mutable, FluentThingInternalUseOnly
qui a soutenu l'élargissement de la conversion en FluentThing
. Les membres courants sur FluentThing
construire une nouvelle instance de FluentThingInternalUseOnly
et avoir ce dernier type comme type de retour; les membres de FluentThingInternalUseOnly
opérerait et reviendrait, this
.
Ceci, si l'on disait FluentThing newThing = oldFluentThing.WithThis(4).WithThat(3).WithOther(57);
, la WithThis
la méthode construire un nouveau FluentThingInternalUseOnly
. Cette même instance serait modifiée et renvoyée par WithThat
et WithOther
; Les données de celles-ci seraient ensuite copiées dans un nouveau FluentThing
dont la référence serait stockée dans newThing
.
Le problème majeur avec cette approche est que si quelqu'un dit dim newThing = oldFluentThing.WithThis(3);
, alors newThing
ne tiendrait pas de référence à un immuable FluentThing
, mais un mutable FluentThingInternalUseOnly
, et cette chose n'aurait aucun moyen de savoir qu'une référence à cela avait été persistée.
Conceptuellement, ce qui est nécessaire est une façon d'avoir FluentThingInternalUseOnly
être suffisamment public pour qu'il puisse être utilisé comme type de retour d'une fonction publique, mais pas le plus public pour permettre au code extérieur de la déclaration de variables de ce type. Malheureusement, je ne sais aucun moyen de le faire, mais peut-être une astuce impliquant Obsolete()
Les balises peuvent être possibles.
Sinon, si les objets en cours sont compliqué devrait être fait à cet objet [les méthodes courantes de chaînage créeraient efficacement une liste liée] et une référence évaluée paresseusement à un objet sur lequel toutes les modifications appropriées avaient été appliquées. Si l'on appelait newThing = myThing.WithBar(3).WithBoz(9).WithBam(42)
, un nouvel objet wrapper serait créé à chaque étape du chemin, et la première tentative d'utilisation newThing
comme une chose devrait construire un Thing
Instance avec trois modifications s'y appliquait, mais l'original myThing
serait intact, et il ne serait que nécessaire de faire une nouvelle instance de Thing
plutôt que trois.