泛型的静态方法

问题描述

在Java中,我有一个类:

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) {
    ...
}

我尝试将其移植到c#,但我对此经验很少。

我定义了这样的类:

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
    }
}

在c#中执行以下java行时遇到问题:static public <T extends PCB_Node<T>> Iterator<T> get_iterator(T e) {。而且我不确定是否有可能,因为到目前为止,我对此一无所获。 我知道我可以在类本身中实现GetEnumerator而不是将其重定向到某个静态方法,但是我更喜欢这种方式。

我想这就是我想要的:

static public IEnumerable<T> get_iterator(T e) where T : PCB_Node<T> {

有可能吗?

解决方法

首先,您的类声明不正确。

您在这里说T必须是PCB_Node<T> 实现IEnumerable<T>

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

您希望PCB_Node<T>实现IEnumerable<T>

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

第二,这可能会导致您出现问题:

get_iterator((T)this)

尽管TPCB_Node<T>this的类型为PCB_Node<T>不一定是T,这会导致运行时异常例如:

class DerivedNode : PCB_Node<DerivedNode> { }

var node = new PCB_Node<DerivedNode>();
var enumerator = node.GetEnumerator(); // InvalidCastException

如果要将GetEnumerator的实现卸载到静态方法中,则需要这样声明:

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)
    {
        //...
    }
}

如果get_iterator在另一个类中声明,则需要重新应用约束:

public class AnotherClass
{
    public static IEnumerator<T> get_iterator<T>(PCB_Node<T> node) where T : PCB_Node<T>
    {
        //...
    }
}

然后像这样呼叫:

public IEnumerator<T> GetEnumerator() => AnotherClass.get_iterator(this);
,

您可能希望具有以下声明:

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

即您的PCB_Node是IEnumerable,并且T必须是相同种类的PCB_Node

我对java中的静态类不熟悉,但是我想您需要一个常规类。

要实现IEnumerable,可以使用iterator block

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

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

我个人会考虑将迭代器与类分开,因为可以用几种不同的方式来迭代树。例如通过使用扩展方法:

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