public TreeNodeDiff(TreeNodeDump node, DiffStatus status) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (status != DiffStatus.Added && status != DiffStatus.Deleted) { throw new ArgumentException(nameof(status)); } Name = node.Name ?? throw new ArgumentNullException(nameof(node.Name)); string type = node.Type ?? throw new ArgumentNullException(nameof(node.Type)); LeftType = status == DiffStatus.Added ? string.Empty : type; RightType = status == DiffStatus.Added ? type : string.Empty; LeftVersion = status == DiffStatus.Added ? 0 : node.Version; RightVersion = status == DiffStatus.Added ? node.Version : 0; LeftAlign = status == DiffStatus.Added ? false : node.IsAlign; RightAlign = status == DiffStatus.Added ? node.IsAlign : false; int childNodeCount = node.GetNodeCount() - 1; TreeNodeDiff emptyElement = childNodeCount == 0 ? null : new TreeNodeDiff(status); TreeNodeDiff[] children = node.Children.Select(t => new TreeNodeDiff(t, status)).ToArray(); TreeNodeDiff[] emptyChildren = Enumerable.Repeat(emptyElement, childNodeCount).ToArray(); LeftChildren = status == DiffStatus.Added ? emptyChildren : children; RightChildren = status == DiffStatus.Added ? children : emptyChildren; Status = DeepStatus = status; }
private TreeNodeDiff(TreeNodeDump left, TreeNodeDump right, bool forceMerge) { if (left == null) { throw new ArgumentNullException(nameof(left)); } if (right == null) { throw new ArgumentNullException(nameof(right)); } if (left.Name != right.Name) { throw new ArgumentException("Left and right names aren't equal"); } Name = left.Name ?? throw new ArgumentNullException(nameof(left.Name)); LeftType = left.Type ?? throw new ArgumentNullException(nameof(left.Type)); RightType = right.Type ?? throw new ArgumentNullException(nameof(left.Type)); LeftVersion = left.Version; RightVersion = right.Version; LeftAlign = left.IsAlign; RightAlign = right.IsAlign; Status = (LeftType == RightType && LeftVersion == RightVersion && LeftAlign == RightAlign) ? DiffStatus.Unchanged : DiffStatus.Changed; if (LeftType == RightType || forceMerge) { TreeNodeDiff[] children = CreateChildren(left, right); LeftChildren = RightChildren = children; DeepStatus = children.All(t => t.DeepStatus == DiffStatus.Unchanged) ? Status : DiffStatus.Changed; } else { int leftNodeCount = left.GetNodeCount(); int rightNodeCount = right.GetNodeCount(); int extraLeft = Math.Max(rightNodeCount - leftNodeCount, 0); int extraRight = Math.Max(leftNodeCount - rightNodeCount, 0); TreeNodeDiff extraElement = leftNodeCount == rightNodeCount ? null : new TreeNodeDiff(DiffStatus.Changed); IEnumerable <TreeNodeDiff> extraLeftChildren = Enumerable.Repeat(extraElement, extraLeft); IEnumerable <TreeNodeDiff> extraRightChildren = Enumerable.Repeat(extraElement, extraRight); LeftChildren = left.Children.Select(t => new TreeNodeDiff(t, false)).Concat(extraLeftChildren).ToArray(); RightChildren = right.Children.Select(t => new TreeNodeDiff(t, true)).Concat(extraRightChildren).ToArray(); DeepStatus = DiffStatus.Changed; } }