public ImmutableNode <TKey, TValue> AddChild(ImmutableNode <TKey, TValue> newChild) { // copy the existing children to a new array, and append the new one. ImmutableNode <TKey, TValue>[] newChildNodes = new ImmutableNode <TKey, TValue> [this.childNodes.Length + 1]; Array.Copy(this.childNodes, newChildNodes, this.childNodes.Length); newChildNodes[this.childNodes.Length] = newChild; // create new node with new child node. return(this.CreateClone(newChildNodes)); }
public ImmutableNode <TKey, TValue> ReplaceChild(ImmutableNode <TKey, TValue> childToReplace, ImmutableNode <TKey, TValue> newChild) { if (object.ReferenceEquals(childToReplace, newChild)) { return(this); // nothing to do } if (!childToReplace.TryGetKey(out var childToReplaceKey)) { throw new ArgumentException("child node must have a key", nameof(childToReplace)); } if (!newChild.TryGetKey(out var newChildKey)) { throw new ArgumentException("child node must have a key", nameof(newChild)); } if (!EqualityComparer <TKey> .Default.Equals(childToReplaceKey, newChildKey)) { throw new InvalidOperationException($"Key of child to replace (key='{childToReplaceKey}') and new child (key='{newChildKey}') must be equal"); } var newNodesChildren = new ImmutableNode <TKey, TValue> [this.childNodes.Length]; bool hasReplaced = false; for (int i = 0; i < this.childNodes.Length; i++) { if (this.childNodes[i].Equals(childToReplace)) { newNodesChildren[i] = newChild; hasReplaced = true; } else { newNodesChildren[i] = this.childNodes[i]; } } if (hasReplaced) { return(this.CreateClone(newNodesChildren)); } throw new InvalidOperationException($"The node (id={newChildKey}) doesn't substutite any of the existing child nodes"); }
public ImmutableNode <TKey, TValue> RemoveChild(ImmutableNode <TKey, TValue> child) { return(this.CreateClone(this.ChildNodes.Except(new[] { child }).ToArray())); }