diff --git a/src/Spectre.Console.Tests/Expectations/TreeRenderingTests.Representative_Tree.verified.txt b/src/Spectre.Console.Tests/Expectations/TreeTests.Should_Render_Tree_Correctly.verified.txt
similarity index 100%
rename from src/Spectre.Console.Tests/Expectations/TreeRenderingTests.Representative_Tree.verified.txt
rename to src/Spectre.Console.Tests/Expectations/TreeTests.Should_Render_Tree_Correctly.verified.txt
diff --git a/src/Spectre.Console.Tests/Expectations/TreeRenderingTests.Root_Node_Only.verified.txt b/src/Spectre.Console.Tests/Expectations/TreeTests.Should_Render_Tree_With_Only_Root_Node_Correctly.verified.txt
similarity index 100%
rename from src/Spectre.Console.Tests/Expectations/TreeRenderingTests.Root_Node_Only.verified.txt
rename to src/Spectre.Console.Tests/Expectations/TreeTests.Should_Render_Tree_With_Only_Root_Node_Correctly.verified.txt
diff --git a/src/Spectre.Console.Tests/Unit/TreeMeasureTests.cs b/src/Spectre.Console.Tests/Unit/TreeMeasureTests.cs
deleted file mode 100644
index 0bb8491..0000000
--- a/src/Spectre.Console.Tests/Unit/TreeMeasureTests.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Spectre.Console.Rendering;
-using Xunit;
-
-namespace Spectre.Console.Tests.Unit
-{
-    public class TreeMeasureTests
-    {
-        [Fact]
-        public void Measure_Tree_Dominated_Width()
-        {
-            // Given
-            var nestedChildren =
-                Enumerable.Range(0, 10)
-                    .Select(x => new TreeNode(new Text($"multiple \n line {x}")));
-            var child3 = new TreeNode(new Text("child3"));
-            child3.AddChild(new TreeNode(new Text("single leaf\n multiline")));
-            var children = new List<TreeNode>
-            {
-                new(new Text("child1"), nestedChildren), new(new Text("child2")), child3,
-            };
-            var root = new TreeNode(new Text("Root node"), children);
-            var tree = new Tree(root);
-
-            // When
-            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
-
-            // Then
-            // Corresponds to "│   └── multiple"
-            Assert.Equal(17, measurement.Min);
-
-            // Corresponds to "    └── single leaf" when untrimmed
-            Assert.Equal(19, measurement.Max);
-        }
-
-        [Fact]
-        public void Measure_Max_Width_Bound()
-        {
-            // Given
-            var root = new TreeNode(new Text("Root node"));
-            var currentNode = root;
-            foreach (var i in Enumerable.Range(0, 100))
-            {
-                var newNode = new TreeNode(new Text(string.Empty));
-                currentNode.AddChild(newNode);
-                currentNode = newNode;
-            }
-
-            var tree = new Tree(root);
-
-            // When
-            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
-
-            // Then
-            // Each node depth contributes 4 characters, so 100 node depth -> 400 character min width
-            Assert.Equal(400, measurement.Min);
-
-            // Successfully capped at 80 terminal width
-            Assert.Equal(80, measurement.Max);
-        }
-
-        [Fact]
-        public void Measure_Leaf_Dominated_Width()
-        {
-            // Given
-            var root = new TreeNode(new Text("Root node"));
-            var currentNode = root;
-            foreach (var i in Enumerable.Range(0, 10))
-            {
-                var newNode = new TreeNode(new Text(string.Empty));
-                currentNode.AddChild(newNode);
-                currentNode = newNode;
-            }
-
-            var tree = new Tree(root);
-
-            // When
-            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
-
-            // Then
-            // Corresponds to "│   │   │   │   │   │   │   │   │   └── "
-            Assert.Equal(40, measurement.Min);
-
-            // Corresponds to "│   │   │   │   │   │   │   │   │   └── "
-            Assert.Equal(40, measurement.Max);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Spectre.Console.Tests/Unit/TreeRenderingTests.cs b/src/Spectre.Console.Tests/Unit/TreeRenderingTests.cs
deleted file mode 100644
index abd5702..0000000
--- a/src/Spectre.Console.Tests/Unit/TreeRenderingTests.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Spectre.Console.Testing;
-using VerifyXunit;
-using Xunit;
-
-namespace Spectre.Console.Tests.Unit
-{
-    [UsesVerify]
-    public sealed class TreeRenderingTests
-    {
-        [Fact]
-        public Task Representative_Tree()
-        {
-            // Given
-            var console = new FakeConsole(width: 80);
-            var nestedChildren =
-                Enumerable.Range(0, 10)
-                    .Select(x => new TreeNode(new Text($"multiple \n line {x}")));
-            var child2 = new TreeNode(new Text("child2"));
-            var child2Child = new TreeNode(new Text("child2Child"));
-            child2.AddChild(child2Child);
-            child2Child.AddChild(new TreeNode(new Text("Child 2 child\n child")));
-            var child3 = new TreeNode(new Text("child3"));
-            var child3Child = new TreeNode(new Text("single leaf\n multiline"));
-            child3Child.AddChild(new TreeNode(new Calendar(2020, 01)));
-            child3.AddChild(child3Child);
-            var children = new List<TreeNode> { new(new Text("child1"), nestedChildren), child2, child3 };
-            var root = new TreeNode(new Text("Root node"), children);
-            var tree = new Tree(root);
-
-            // When
-            console.Render(tree);
-
-            // Then
-            return Verifier.Verify(console.Output);
-        }
-
-        [Fact]
-        public Task Root_Node_Only()
-        {
-            // Given
-            var console = new FakeConsole(width: 80);
-            var root = new TreeNode(new Text("Root node"), Enumerable.Empty<TreeNode>());
-            var tree = new Tree(root);
-
-            // When
-            console.Render(tree);
-
-            // Then
-            return Verifier.Verify(console.Output);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Spectre.Console.Tests/Unit/TreeTests.cs b/src/Spectre.Console.Tests/Unit/TreeTests.cs
new file mode 100644
index 0000000..1cb755b
--- /dev/null
+++ b/src/Spectre.Console.Tests/Unit/TreeTests.cs
@@ -0,0 +1,128 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Shouldly;
+using Spectre.Console.Rendering;
+using Spectre.Console.Testing;
+using VerifyXunit;
+using Xunit;
+
+namespace Spectre.Console.Tests.Unit
+{
+    [UsesVerify]
+    public class TreeTests
+    {
+        [Fact]
+        public void Should_Measure_Tree_Correctly()
+        {
+            // Given
+            var nestedChildren =
+                Enumerable.Range(0, 10)
+                    .Select(x => new TreeNode(new Text($"multiple \n line {x}")));
+            var child3 = new TreeNode(new Text("child3"));
+            child3.AddChild(new TreeNode(new Text("single leaf\n multiline")));
+            var children = new List<TreeNode>
+            {
+                new(new Text("child1"), nestedChildren), new(new Text("child2")), child3,
+            };
+            var root = new TreeNode(new Text("Root node"), children);
+            var tree = new Tree(root);
+
+            // When
+            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
+
+            // Then
+            measurement.Min.ShouldBe(17);
+            measurement.Max.ShouldBe(19);
+        }
+
+        [Fact]
+        public void Should_Measure_Tree_Correctly_With_Regard_To_Max_Width()
+        {
+            // Given
+            var root = new TreeNode(new Text("Root node"));
+            var currentNode = root;
+            foreach (var i in Enumerable.Range(0, 100))
+            {
+                var newNode = new TreeNode(new Text(string.Empty));
+                currentNode.AddChild(newNode);
+                currentNode = newNode;
+            }
+
+            var tree = new Tree(root);
+
+            // When
+            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
+
+            // Then
+            measurement.Min.ShouldBe(400);
+            measurement.Max.ShouldBe(80);
+        }
+
+        [Fact]
+        public void Measure_Leaf_Dominated_Width()
+        {
+            // Given
+            var root = new TreeNode(new Text("Root node"));
+            var currentNode = root;
+            foreach (var i in Enumerable.Range(0, 10))
+            {
+                var newNode = new TreeNode(new Text(i.ToString()));
+                currentNode.AddChild(newNode);
+                currentNode = newNode;
+            }
+
+            var tree = new Tree(root);
+
+            // When
+            var measurement = ((IRenderable)tree).Measure(new RenderContext(Encoding.Unicode, false), 80);
+
+            // Then
+            measurement.Min.ShouldBe(41);
+            measurement.Max.ShouldBe(41);
+        }
+
+        [Fact]
+        public Task Should_Render_Tree_Correctly()
+        {
+            // Given
+            var console = new FakeConsole(width: 80);
+            var nestedChildren =
+                Enumerable.Range(0, 10)
+                    .Select(x => new TreeNode(new Text($"multiple \n line {x}")));
+            var child2 = new TreeNode(new Text("child2"));
+            var child2Child = new TreeNode(new Text("child2Child"));
+            child2.AddChild(child2Child);
+            child2Child.AddChild(new TreeNode(new Text("Child 2 child\n child")));
+            var child3 = new TreeNode(new Text("child3"));
+            var child3Child = new TreeNode(new Text("single leaf\n multiline"));
+            child3Child.AddChild(new TreeNode(new Calendar(2020, 01)));
+            child3.AddChild(child3Child);
+            var children = new List<TreeNode> { new(new Text("child1"), nestedChildren), child2, child3 };
+            var root = new TreeNode(new Text("Root node"), children);
+            var tree = new Tree(root);
+
+            // When
+            console.Render(tree);
+
+            // Then
+            return Verifier.Verify(console.Output);
+        }
+
+        [Fact]
+        public Task Should_Render_Tree_With_Only_Root_Node_Correctly()
+        {
+            // Given
+            var console = new FakeConsole(width: 80);
+            var root = new TreeNode(new Text("Root node"), Enumerable.Empty<TreeNode>());
+            var tree = new Tree(root);
+
+            // When
+            console.Render(tree);
+
+            // Then
+            return Verifier.Verify(console.Output);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Spectre.Console/Extensions/HasTreeNodeExtensions.cs b/src/Spectre.Console/Extensions/HasTreeNodeExtensions.cs
new file mode 100644
index 0000000..945a7f8
--- /dev/null
+++ b/src/Spectre.Console/Extensions/HasTreeNodeExtensions.cs
@@ -0,0 +1,27 @@
+namespace Spectre.Console
+{
+    /// <summary>
+    /// Contains extension methods for <see cref="IHasCulture"/>.
+    /// </summary>
+    public static class HasTreeNodeExtensions
+    {
+        /// <summary>
+        /// Adds a child to the end of the node's list of children.
+        /// </summary>
+        /// <typeparam name="T">An object type with tree nodes.</typeparam>
+        /// <param name="obj">The object that has tree nodes.</param>
+        /// <param name="child">Child to be added.</param>
+        /// <returns>The same instance so that multiple calls can be chained.</returns>
+        public static T AddChild<T>(this T obj, TreeNode child)
+            where T : class, IHasTreeNodes
+        {
+            if (obj is null)
+            {
+                throw new System.ArgumentNullException(nameof(obj));
+            }
+
+            obj.Children.Add(child);
+            return obj;
+        }
+    }
+}
diff --git a/src/Spectre.Console/IHasTreeNodes.cs b/src/Spectre.Console/IHasTreeNodes.cs
new file mode 100644
index 0000000..bbed370
--- /dev/null
+++ b/src/Spectre.Console/IHasTreeNodes.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace Spectre.Console
+{
+    /// <summary>
+    /// Represents something that has tree nodes.
+    /// </summary>
+    public interface IHasTreeNodes
+    {
+        /// <summary>
+        /// Gets the children of this node.
+        /// </summary>
+        public List<TreeNode> Children { get; }
+    }
+}
diff --git a/src/Spectre.Console/Rendering/AsciiTreeRendering.cs b/src/Spectre.Console/Rendering/Tree/AsciiTreeAppearance.cs
similarity index 77%
rename from src/Spectre.Console/Rendering/AsciiTreeRendering.cs
rename to src/Spectre.Console/Rendering/Tree/AsciiTreeAppearance.cs
index 92e2cc4..2e4d236 100644
--- a/src/Spectre.Console/Rendering/AsciiTreeRendering.cs
+++ b/src/Spectre.Console/Rendering/Tree/AsciiTreeAppearance.cs
@@ -5,10 +5,13 @@ namespace Spectre.Console.Rendering
     /// <summary>
     /// An ASCII rendering of a tree.
     /// </summary>
-    public sealed class AsciiTreeRendering : ITreeRendering
+    public sealed class AsciiTreeAppearance : TreeAppearance
     {
         /// <inheritdoc/>
-        public string GetPart(TreePart part)
+        public override int PartSize => 4;
+
+        /// <inheritdoc/>
+        public override string GetPart(TreePart part)
         {
             return part switch
             {
@@ -18,8 +21,5 @@ namespace Spectre.Console.Rendering
                 _ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."),
             };
         }
-
-        /// <inheritdoc/>
-        public int PartSize => 4;
     }
 }
\ No newline at end of file
diff --git a/src/Spectre.Console/Rendering/TreeRendering.cs b/src/Spectre.Console/Rendering/TreeRendering.cs
deleted file mode 100644
index 2bb00f5..0000000
--- a/src/Spectre.Console/Rendering/TreeRendering.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Spectre.Console.Rendering
-{
-    /// <summary>
-    /// Selection of different renderings which can be used by <see cref="Tree"/>.
-    /// </summary>
-    public static class TreeRendering
-    {
-        /// <summary>
-        /// Gets ASCII rendering of a tree.
-        /// </summary>
-        public static ITreeRendering Ascii { get; } = new AsciiTreeRendering();
-    }
-}
\ No newline at end of file
diff --git a/src/Spectre.Console/TreeAppearance.Known.cs b/src/Spectre.Console/TreeAppearance.Known.cs
new file mode 100644
index 0000000..4cbb85c
--- /dev/null
+++ b/src/Spectre.Console/TreeAppearance.Known.cs
@@ -0,0 +1,15 @@
+using Spectre.Console.Rendering;
+
+namespace Spectre.Console
+{
+    /// <summary>
+    /// Represents a tree appearance.
+    /// </summary>
+    public abstract partial class TreeAppearance
+    {
+        /// <summary>
+        /// Gets ASCII rendering of a tree.
+        /// </summary>
+        public static TreeAppearance Ascii { get; } = new AsciiTreeAppearance();
+    }
+}
diff --git a/src/Spectre.Console/Rendering/ITreeRendering.cs b/src/Spectre.Console/TreeAppearance.cs
similarity index 64%
rename from src/Spectre.Console/Rendering/ITreeRendering.cs
rename to src/Spectre.Console/TreeAppearance.cs
index 38c2bcc..077c745 100644
--- a/src/Spectre.Console/Rendering/ITreeRendering.cs
+++ b/src/Spectre.Console/TreeAppearance.cs
@@ -1,20 +1,22 @@
-namespace Spectre.Console.Rendering
+using Spectre.Console.Rendering;
+
+namespace Spectre.Console
 {
     /// <summary>
-    /// Represents the characters used to render a tree.
+    /// Represents a tree appearance.
     /// </summary>
-    public interface ITreeRendering
+    public abstract partial class TreeAppearance
     {
+        /// <summary>
+        /// Gets the length of all tree part strings.
+        /// </summary>
+        public abstract int PartSize { get; }
+
         /// <summary>
         /// Get the set of characters used to render the corresponding <see cref="TreePart"/>.
         /// </summary>
         /// <param name="part">The part of the tree to get rendering string for.</param>
         /// <returns>Rendering string for the tree part.</returns>
-        string GetPart(TreePart part);
-
-        /// <summary>
-        /// Gets the length of all tree part strings.
-        /// </summary>
-        int PartSize { get; }
+        public abstract string GetPart(TreePart part);
     }
 }
\ No newline at end of file
diff --git a/src/Spectre.Console/Widgets/Tree.cs b/src/Spectre.Console/Widgets/Tree.cs
index 4cc9d96..e613dc6 100644
--- a/src/Spectre.Console/Widgets/Tree.cs
+++ b/src/Spectre.Console/Widgets/Tree.cs
@@ -19,9 +19,9 @@ namespace Spectre.Console
         public Style Style { get; set; } = Style.Plain;
 
         /// <summary>
-        ///  Gets or sets the rendering type used for the tree.
+        ///  Gets or sets the appearance of the tree.
         /// </summary>
-        public ITreeRendering Rendering { get; set; } = TreeRendering.Ascii;
+        public TreeAppearance Appearance { get; set; } = TreeAppearance.Ascii;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="Tree"/> class.
@@ -29,37 +29,37 @@ namespace Spectre.Console
         /// <param name="rootNode">Root node of the tree to be rendered.</param>
         public Tree(TreeNode rootNode)
         {
-            _rootNode = rootNode;
+            _rootNode = rootNode ?? throw new ArgumentNullException(nameof(rootNode));
         }
 
         /// <inheritdoc />
         protected override Measurement Measure(RenderContext context, int maxWidth)
         {
-            return MeasureAtDepth(context, maxWidth, _rootNode, depth: 0);
-        }
-
-        private Measurement MeasureAtDepth(RenderContext context, int maxWidth, TreeNode node, int depth)
-        {
-            var rootMeasurement = node.Measure(context, maxWidth);
-            var treeIndentation = depth * Rendering.PartSize;
-            var currentMax = rootMeasurement.Max + treeIndentation;
-            var currentMin = rootMeasurement.Min + treeIndentation;
-
-            foreach (var child in node.Children)
+            Measurement MeasureAtDepth(RenderContext context, int maxWidth, TreeNode node, int depth)
             {
-                var childMeasurement = MeasureAtDepth(context, maxWidth, child, depth + 1);
-                if (childMeasurement.Min > currentMin)
+                var rootMeasurement = node.Measure(context, maxWidth);
+                var treeIndentation = depth * Appearance.PartSize;
+                var currentMax = rootMeasurement.Max + treeIndentation;
+                var currentMin = rootMeasurement.Min + treeIndentation;
+
+                foreach (var child in node.Children)
                 {
-                    currentMin = childMeasurement.Min;
+                    var childMeasurement = MeasureAtDepth(context, maxWidth, child, depth + 1);
+                    if (childMeasurement.Min > currentMin)
+                    {
+                        currentMin = childMeasurement.Min;
+                    }
+
+                    if (childMeasurement.Max > currentMax)
+                    {
+                        currentMax = childMeasurement.Max;
+                    }
                 }
 
-                if (childMeasurement.Max > currentMax)
-                {
-                    currentMax = childMeasurement.Max;
-                }
+                return new Measurement(currentMin, Math.Min(currentMax, maxWidth));
             }
 
-            return new Measurement(currentMin, Math.Min(currentMax, maxWidth));
+            return MeasureAtDepth(context, maxWidth, _rootNode, depth: 0);
         }
 
         /// <inheritdoc />
@@ -68,27 +68,25 @@ namespace Spectre.Console
             return _rootNode
                 .Render(context, maxWidth)
                 .Concat(new List<Segment> { Segment.LineBreak })
-                .Concat(RenderChildren(context, maxWidth - Rendering.PartSize, _rootNode, depth: 0));
+                .Concat(RenderChildren(context, maxWidth - Appearance.PartSize, _rootNode, depth: 0));
         }
 
         private IEnumerable<Segment> RenderChildren(RenderContext context, int maxWidth, TreeNode node, int depth,
             int? trailingStarted = null)
         {
             var result = new List<Segment>();
-
-            foreach (var (index, firstChild, lastChild, childNode) in node.Children.Enumerate())
+            foreach (var (_, _, lastChild, childNode) in node.Children.Enumerate())
             {
                 var lines = Segment.SplitLines(context, childNode.Render(context, maxWidth));
-
-                foreach (var (lineIndex, firstLine, lastLine, line) in lines.Enumerate())
+                foreach (var (_, isFirstLine, _, line) in lines.Enumerate())
                 {
                     var siblingConnectorSegment =
-                        new Segment(Rendering.GetPart(TreePart.SiblingConnector), Style);
+                        new Segment(Appearance.GetPart(TreePart.SiblingConnector), Style);
                     if (trailingStarted != null)
                     {
                         result.AddRange(Enumerable.Repeat(siblingConnectorSegment, trailingStarted.Value));
                         result.AddRange(Enumerable.Repeat(
-                            Segment.Padding(Rendering.PartSize),
+                            Segment.Padding(Appearance.PartSize),
                             depth - trailingStarted.Value));
                     }
                     else
@@ -96,15 +94,15 @@ namespace Spectre.Console
                         result.AddRange(Enumerable.Repeat(siblingConnectorSegment, depth));
                     }
 
-                    if (firstLine)
+                    if (isFirstLine)
                     {
                         result.Add(lastChild
-                            ? new Segment(Rendering.GetPart(TreePart.BottomChildBranch), Style)
-                            : new Segment(Rendering.GetPart(TreePart.ChildBranch), Style));
+                            ? new Segment(Appearance.GetPart(TreePart.BottomChildBranch), Style)
+                            : new Segment(Appearance.GetPart(TreePart.ChildBranch), Style));
                     }
                     else
                     {
-                        result.Add(lastChild ? Segment.Padding(Rendering.PartSize) : siblingConnectorSegment);
+                        result.Add(lastChild ? Segment.Padding(Appearance.PartSize) : siblingConnectorSegment);
                     }
 
                     result.AddRange(line);
@@ -112,8 +110,12 @@ namespace Spectre.Console
                 }
 
                 var childTrailingStarted = trailingStarted ?? (lastChild ? depth : null);
-                result.AddRange(RenderChildren(context, maxWidth - Rendering.PartSize, childNode, depth + 1,
-                    childTrailingStarted));
+
+                result.AddRange(
+                    RenderChildren(
+                        context, maxWidth - Appearance.PartSize,
+                        childNode, depth + 1,
+                        childTrailingStarted));
             }
 
             return result;
diff --git a/src/Spectre.Console/Widgets/TreeNode.cs b/src/Spectre.Console/Widgets/TreeNode.cs
index 724732b..d7c19d2 100644
--- a/src/Spectre.Console/Widgets/TreeNode.cs
+++ b/src/Spectre.Console/Widgets/TreeNode.cs
@@ -1,3 +1,4 @@
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using Spectre.Console.Rendering;
@@ -7,10 +8,12 @@ namespace Spectre.Console
     /// <summary>
     /// Node of a tree.
     /// </summary>
-    public sealed class TreeNode : IRenderable
+    public sealed class TreeNode : IHasTreeNodes, IRenderable
     {
         private readonly IRenderable _renderable;
-        private List<TreeNode> _children;
+
+        /// <inheritdoc/>
+        public List<TreeNode> Children { get; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="TreeNode"/> class.
@@ -19,25 +22,8 @@ namespace Spectre.Console
         /// <param name="children">Any children that the node is declared with.</param>
         public TreeNode(IRenderable renderable, IEnumerable<TreeNode>? children = null)
         {
-            _renderable = renderable;
-            _children = new List<TreeNode>(children ?? Enumerable.Empty<TreeNode>());
-        }
-
-        /// <summary>
-        /// Gets the children of this node.
-        /// </summary>
-        public List<TreeNode> Children
-        {
-            get => _children;
-        }
-
-        /// <summary>
-        /// Adds a child to the end of the node's list of children.
-        /// </summary>
-        /// <param name="child">Child to be added.</param>
-        public void AddChild(TreeNode child)
-        {
-            _children.Add(child);
+            _renderable = renderable ?? throw new ArgumentNullException(nameof(renderable));
+            Children = new List<TreeNode>(children ?? Enumerable.Empty<TreeNode>());
         }
 
         /// <inheritdoc/>