Skip to content

Commit 273add9

Browse files
author
Oren (electricessence)
committed
Added nullable support.
1 parent 1796781 commit 273add9

5 files changed

Lines changed: 60 additions & 47 deletions

File tree

IChild.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ public interface IChild
77
/// <summary>
88
/// The parent of this child.
99
/// </summary>
10-
object Parent { get; }
10+
object? Parent { get; }
1111
}
1212

1313
public interface IChild<out TParent> : IChild
14+
where TParent : class
1415
{
1516
/// <summary>
1617
/// The generic parent of this child.
1718
/// </summary>
18-
new TParent Parent { get; }
19+
new TParent? Parent { get; }
1920
}
2021

2122
public static class ChildExtensions
@@ -28,9 +29,9 @@ public static class ChildExtensions
2829
/// <returns>An enumerable of the ancestors.</returns>
2930
public static IEnumerable<TNode> GetAncestors<TNode>(
3031
this TNode node)
31-
where TNode : IChild<TNode>
32+
where TNode : class, IChild<TNode>
3233
{
33-
TNode parent;
34+
TNode? parent;
3435
while ((parent = node.Parent) != null)
3536
{
3637
yield return parent;
@@ -46,9 +47,9 @@ public static IEnumerable<TNode> GetAncestors<TNode>(
4647
/// <returns>The root node.</returns>
4748
public static TNode GetRoot<TNode>(
4849
this TNode node)
49-
where TNode : IChild<TNode>
50+
where TNode : class, IChild<TNode>
5051
{
51-
TNode parent;
52+
TNode? parent;
5253
while ((parent = node.Parent) != null)
5354
{
5455
node = parent;

INode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Open.Hierarchy
44
{
55
public interface INode<TNode> : IList<TNode>, IChild<TNode>, IParent<TNode>, IHaveRoot<TNode>
6-
where TNode : INode<TNode>
6+
where TNode : class, INode<TNode>
77
{
88
}
99

Node.Clone.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Diagnostics.Contracts;
34

45
namespace Open.Hierarchy
@@ -17,8 +18,8 @@ public sealed partial class Node<T>
1718
/// <param name="onNodeCloned">A function that recieves the old node and its clone.</param>
1819
/// <returns>The copy of the tree/branch.</returns>
1920
public Node<T> Clone(
20-
Node<T> newParentForClone = null,
21-
Action<Node<T>, Node<T>> onNodeCloned = null)
21+
Node<T>? newParentForClone = null,
22+
Action<Node<T>, Node<T>>? onNodeCloned = null)
2223
{
2324
if (newParentForClone != null && newParentForClone._factory != _factory)
2425
throw new ArgumentException("The node being provided for cloning does not belong to this factory.", nameof(newParentForClone));
@@ -56,13 +57,14 @@ public Node<T> Clone(
5657
/// <returns>A clone of this node as part of a newly cloned tree.</returns>
5758
public Node<T> CloneTree()
5859
{
59-
Node<T> node = null;
60+
Node<T>? node = null;
6061
Root.Clone((original, clone) =>
6162
{
6263
if (original == this)
6364
node = clone;
6465
});
65-
return node;
66+
Debug.Assert(node != null);
67+
return node!;
6668
}
6769

6870
}

Node.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Diagnostics.CodeAnalysis;
45
using System.Diagnostics.Contracts;
56

67
namespace Open.Hierarchy
78
{
89
public sealed partial class Node<T> : INode<Node<T>>
910
{
10-
public Node<T> Parent { get; private set; }
11-
object IChild.Parent => Parent;
11+
public Node<T>? Parent { get; private set; }
12+
object? IChild.Parent => Parent;
1213

1314
#region IParent<Node<T>> Implementation
1415
private readonly List<Node<T>> _children;
@@ -20,7 +21,9 @@ public sealed partial class Node<T> : INode<Node<T>>
2021
IReadOnlyList<object> IParent.Children => EnsureChildrenMapped();
2122
#endregion
2223

24+
#pragma warning disable IDE0044 // Add readonly modifier
2325
private bool _recycled;
26+
#pragma warning restore IDE0044 // Add readonly modifier
2427
void AssertNotRecycled()
2528
{
2629
if (_recycled)
@@ -32,6 +35,9 @@ void AssertNotRecycled()
3235
/// The value for the node to hold on to.
3336
/// </summary>
3437
private T _value;
38+
#if NETSTANDARD2_1
39+
[MaybeNull]
40+
#endif
3541
public T Value
3642
{
3743
get => _value;
@@ -82,6 +88,7 @@ IReadOnlyList<Node<T>> EnsureChildrenMapped()
8288
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
8389
_children = new List<Node<T>>();
8490
_childrenReadOnly = _children.AsReadOnly();
91+
_value = default!;
8592
}
8693

8794
// WARNING: Care must be taken not to have duplicate nodes anywhere in the tree but having duplicate values are allowed.
@@ -263,7 +270,7 @@ public Node<T> Root
263270
get
264271
{
265272
var current = this;
266-
Node<T> parent;
273+
Node<T>? parent;
267274
while ((parent = current.Parent) != null)
268275
{
269276
current = parent;
@@ -280,7 +287,7 @@ public Node<T> Root
280287
public void Teardown()
281288
{
282289
Unmapped = false;
283-
Value = default;
290+
Value = default!;
284291
Detatch(); // If no parent then this does nothing...
285292
TeardownChildren();
286293
}
@@ -311,7 +318,7 @@ public T Recycle()
311318
AssertNotRecycled(); // Avoid double entry in the pool.
312319
Unmapped = false;
313320
var value = Value;
314-
Value = default;
321+
Value = default!;
315322
Detatch(); // If no parent then this does nothing...
316323
RecycleChildren();
317324
return value;

Open.Hierarchy.csproj

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
5-
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
6-
<Authors>electricessence</Authors>
7-
<Company>electricessence</Company>
8-
<Description>Interfaces and classes helful in managing tree-like data structures.
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
5+
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
6+
<Authors>electricessence</Authors>
7+
<Company>electricessence</Company>
8+
<Description>
9+
Interfaces and classes helful in managing tree-like data structures.
910

10-
Part of the "Open" set of libraries.</Description>
11-
<Copyright>https://github.com/electricessence/Open.Hierarchy/blob/master/LICENSE</Copyright>
12-
<PackageLicenseUrl></PackageLicenseUrl>
13-
<PackageProjectUrl>https://github.com/electricessence/Open.Hierarchy/</PackageProjectUrl>
14-
<RepositoryUrl>https://github.com/electricessence/Open.Hierarchy/</RepositoryUrl>
15-
<RepositoryType>git</RepositoryType>
16-
<PackageTags>dotnet, dotnetcore, cs, tree, node, hierarchy, parent, child, root</PackageTags>
17-
<Version>1.6.2</Version>
18-
<PackageReleaseNotes></PackageReleaseNotes>
19-
<PackageLicenseExpression>MIT</PackageLicenseExpression>
20-
</PropertyGroup>
11+
Part of the "Open" set of libraries.
12+
</Description>
13+
<Copyright>https://github.com/electricessence/Open.Hierarchy/blob/master/LICENSE</Copyright>
14+
<PackageLicenseUrl></PackageLicenseUrl>
15+
<PackageProjectUrl>https://github.com/electricessence/Open.Hierarchy/</PackageProjectUrl>
16+
<RepositoryUrl>https://github.com/electricessence/Open.Hierarchy/</RepositoryUrl>
17+
<RepositoryType>git</RepositoryType>
18+
<PackageTags>dotnet, dotnetcore, cs, tree, node, hierarchy, parent, child, root</PackageTags>
19+
<Version>1.7.0</Version>
20+
<PackageReleaseNotes></PackageReleaseNotes>
21+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
22+
<Nullable>enable</Nullable>
23+
</PropertyGroup>
2124

22-
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
23-
<LangVersion>latest</LangVersion>
24-
</PropertyGroup>
25+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
26+
<LangVersion>latest</LangVersion>
27+
</PropertyGroup>
2528

26-
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
27-
<LangVersion>latest</LangVersion>
28-
</PropertyGroup>
29+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
30+
<LangVersion>latest</LangVersion>
31+
</PropertyGroup>
2932

30-
<ItemGroup>
31-
<None Remove=".git" />
32-
<None Remove=".gitignore" />
33-
<None Remove="LICENSE" />
34-
</ItemGroup>
33+
<ItemGroup>
34+
<None Remove=".git" />
35+
<None Remove=".gitignore" />
36+
<None Remove="LICENSE" />
37+
</ItemGroup>
3538

36-
<ItemGroup>
37-
<PackageReference Include="Open.Disposable.ObjectPools" Version="2.3.3" />
38-
</ItemGroup>
39+
<ItemGroup>
40+
<PackageReference Include="Open.Disposable.ObjectPools" Version="2.4.0" />
41+
</ItemGroup>
3942

4043
</Project>

0 commit comments

Comments
 (0)