In java I have a class:
static public class PCB_Node<T extends PCB_Node<T>> implements Iterable<T> {
public T parent;
public T first_child;
public T next_brother;
public Iterator<T> iterator() {
return get_iterator((T)this);
}
}
static public <T extends PCB_Node<T>> Iterator<T> get_iterator(T e) {
...
}
I attempt to do port this to c#, in which I have very little experience.
I defined the class like this:
public class PCB_Node<T> where T : PCB_Node<T>, IEnumerable<T> {
public T parent;
public T first_child;
public T next_brother;
public IEnumerator<T> GetEnumerator() {
return get_iterator((T)this); // << not sure about this, but that also depends on if it is possible
}
}
I have problems with doing the following java line in c#: static public <T extends PCB_Node<T>> Iterator<T> get_iterator(T e) {
. And I'm not sure if it's even possible, cause so far, I can't find anything about it.
I know I can implement GetEnumerator
in the class itself instead of redirecting it to some static method, but I prefer it this way.
I guess this is what I want:
static public IEnumerable<T> get_iterator(T e) where T : PCB_Node<T> {
Is something like that possible?
Firstly, your class declaration is not correct.
Here you are saying that T
must be a PCB_Node<T>
and implement IEnumerable<T>
:
public class PCB_Node<T> where T : PCB_Node<T>, IEnumerable<T>
Whereas you want PCB_Node<T>
to implement IEnumerable<T>
:
public class PCB_Node<T> : IEnumerable<T> where T : PCB_Node<T>
Secondly, this could cause you problems:
get_iterator((T)this)
Although T
is a PCB_Node<T>
, this
, being of type PCB_Node<T>
is not necessarily a T
, which would lead to a runtime exception in this example:
class DerivedNode : PCB_Node<DerivedNode> { }
var node = new PCB_Node<DerivedNode>();
var enumerator = node.GetEnumerator(); // InvalidCastException
If you want to offload the implementation of GetEnumerator
to a static method, you would need to declare it like this:
public class PCB_Node<T> : IEnumerable<T> where T : PCB_Node<T>
{
public IEnumerator<T> GetEnumerator() => get_iterator(this);
public static IEnumerator<T> get_iterator(PCB_Node<T> node)
{
//...
}
}
If get_iterator
is declared in another class, you would need to reapply the constraint:
public class AnotherClass
{
public static IEnumerator<T> get_iterator<T>(PCB_Node<T> node) where T : PCB_Node<T>
{
//...
}
}
Then call like this:
public IEnumerator<T> GetEnumerator() => AnotherClass.get_iterator(this);