C
C#2y ago
potzko

❔ help with self referential class typing

I was trying to make a node class I can inherit from and ran into a ton of trouble, in my original solution the "next" value was still a node rather then the child class, I looked around and people were saying to use a self referential generic class signature so I used this:
public class Node<Self, T>
where Self: Node<Self, T>
{
public T value;
public Self? next;
}
public class Node<Self, T>
where Self: Node<Self, T>
{
public T value;
public Self? next;
}
and started writing, I even got some inheritance to work,
public class CmpNode<T>: Node<CmpNode<T>, T>
where T: IComparable
{
public CmpNode(T value) : base(value) { }
public CmpNode(T value, CmpNode<T> next) : base(value, next) { }

public CmpNode<T> getMaxNode(){
var max = this;
var point = this;
while (point!.hasNext()){
if (max.value.CompareTo(point.value) == -1){
max = point;
}
point = point.next;
}
if (max.value.CompareTo(point.value) == -1){
max = point;
}
return max;
}
}
public class CmpNode<T>: Node<CmpNode<T>, T>
where T: IComparable
{
public CmpNode(T value) : base(value) { }
public CmpNode(T value, CmpNode<T> next) : base(value, next) { }

public CmpNode<T> getMaxNode(){
var max = this;
var point = this;
while (point!.hasNext()){
if (max.value.CompareTo(point.value) == -1){
max = point;
}
point = point.next;
}
if (max.value.CompareTo(point.value) == -1){
max = point;
}
return max;
}
}
however I ran into a few problems in some of the functions:
public static Self? fromArr(T[] arr){
if (arr.Length == 0){
return null;
}
var start = new Self(arr[0]);
var point = start;
foreach (T item in arr.Skip(1))
{
point.next = new Self(item);
}
return start;
}
public static Self? fromArr(T[] arr){
if (arr.Length == 0){
return null;
}
var start = new Self(arr[0]);
var point = start;
foreach (T item in arr.Skip(1))
{
point.next = new Self(item);
}
return start;
}
in this function for example, how can I make a new "Self" object? as I do not know what constructors it has. and if I try to build a node I cant set it as next as I expect a Self object, am I missing a trick to get this to work?
6 Replies
jalepi
jalepi2y ago
var self = (Self)Activator.CreateInstance(typeof(Self), item);
potzko
potzkoOP2y ago
ah so I can go to the constructors of Self as a function argument, ty it works ty 🙂
Jimmacle
Jimmacle2y ago
you can use the new() generic type constraint which would allow you to instantiate the type but require it to define a parameterless constructor what benefits is inheritance giving you here? if it's just to add a couple fields it doesn't seem worth it
potzko
potzkoOP2y ago
I do need to use constructors tho so I cant just have an empty use I cut out some parts of the code as they were irrelevant I have some methods like splice and stuff
phaseshift
phaseshift2y ago
You can have static members on interfaces now. One idea is to use such a static method as a 'named ctor'. You can then constrain Self to implement that interface
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server