问题描述
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)
尽管T
是PCB_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
}