How to allow a Generic class to have itself as a type and required property

3 days ago 5
ARTICLE AD BOX

I have a generic class for a "general" tree node as follows (simplified):

public class GeneralTreeNode<V> { public virtual GeneralTreeNode<V>? Parent { get; set; } public virtual List<GeneralTreeNode<V>> Children { get; set; } = new List<GeneralTreeNode<V>>(); public virtual V Value { get; set; } public GeneralTreeNode(V value, GeneralTreeNode<V>? parent = null) { Value = value; Parent = parent; } //public GeneralTreeNode() { Value = (V)this; } // (not allowed: Cannot convert...) public virtual GeneralTreeNode<V> AddChild(V childValue) { var childNode = new GeneralTreeNode<V>(childValue, this); Children.Add(childNode); return childNode; } }

Sometimes I will use this class as a typical container: the Node contains or points to the content of the node through the Value property. This works as expected.

However, sometimes I also want to use it where the Content object actually inherits the GeneralTreeNode class so that the Value property points to this. The reason for this is that these inheriting classes will be adding additional pointers/links to other instances of the same class, and they need to be aware of and have access to their GeneralTreeNode pointers and structure. (Unlike a typical "contained" class which is unaware of its container and external structure).

The problem is that I keep getting errors relating to requirements for setting/initializing the Value property. Here is a simple example:

// Example "integrated" use: public class IntegratedValueNode : GeneralTreeNode<IntegratedValueNode> { public int whatever { get; set; } = 0; //public IntegratedValueNode() { Value = this; } // (not allowed: No argument corresponds to the required formal parameter...) //public IntegratedValueNode() : base(this) { } // (not allowed: 'this' not available) }

(the code comments above show various things I have tried to resolve this)

I am pretty sure that I used to be able to do this (c. 2010?) before c# started imposing the various "non-nullable objects" criteria that is requiring the property to be initialized by the base class before it gets to the inheriting class's constructor.

Is there any simple way to do this without having to go to an Interface or making the property nullable? I don't want to make the value nullable because it never IS null after initialization and I don't want to have to impose spurious null-checks on all of the code that will access it. I am using VS2022.

Read Entire Article