0

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?

3
  • @AluanHaddad No the C sharp class MUST NOT be static, cause I need to be able to make instances. Commented Sep 25, 2020 at 9:27
  • sorry I always forget that static only applies to nested classes Commented Sep 25, 2020 at 10:13
  • @AluanHaddad no problem my friend Commented Sep 25, 2020 at 12:36

2 Answers 2

1

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);
Sign up to request clarification or add additional context in comments.

3 Comments

I tried the static method that you did in AnotherClass but then I get: "The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)".
@clankill3r Apologies; typo. You need to declare the method as generic i.e. get_iterator<T>.
damn you are quick with responding :D
0

You probably want to have the following declaration:

public class PCB_Node<T> : IEnumerable<T> where T : PCB_Node<T>

I.e. Your PCB_Node is a IEnumerable, and that T has to be the same kind of PCB_Node

I'm not familiar with static classes in java , but you I would guess you want a regular class.

To implement the IEnumerable you can use a iterator block:

    public IEnumerator<T> GetEnumerator()
    {
        yield return this
        // add iteration logic
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

Personally I would consider separating the iterator from the class, since a tree can be iterated in several different ways. for example by using an extension method:

public static IEnumerable<T> DepthFirst<T>(this PCB_Node<T> root) where T : PCB_Node<T>
{
    yield return root;
    // add iteration logic
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.