带有泛型的静态方法
static method with generics
在 java 我有一个 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) {
...
}
我尝试将其移植到 c#,我在这方面的经验很少。
我这样定义 class:
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) {
。而且我不确定这是否可能,因为到目前为止,我找不到任何相关信息。
我知道我可以在 class 本身中实现 GetEnumerator
而不是将其重定向到某个静态方法,但我更喜欢这种方式。
我想这就是我想要的:
static public IEnumerable<T> get_iterator(T e) where T : PCB_Node<T> {
这样的事情可能吗?
首先,您的class声明不正确。
你在这里说 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)
{
//...
}
}
如果在另一个 class 中声明了 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 中的静态 classes,但我猜你想要一个常规的 class.
要实现 IEnumerable,您可以使用 iterator block:
public IEnumerator<T> GetEnumerator()
{
yield return this
// add iteration logic
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
我个人会考虑将迭代器与 class 分开,因为可以用几种不同的方式迭代树。例如通过使用扩展方法:
public static IEnumerable<T> DepthFirst<T>(this PCB_Node<T> root) where T : PCB_Node<T>
{
yield return root;
// add iteration logic
}
在 java 我有一个 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) {
...
}
我尝试将其移植到 c#,我在这方面的经验很少。
我这样定义 class:
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) {
。而且我不确定这是否可能,因为到目前为止,我找不到任何相关信息。
我知道我可以在 class 本身中实现 GetEnumerator
而不是将其重定向到某个静态方法,但我更喜欢这种方式。
我想这就是我想要的:
static public IEnumerable<T> get_iterator(T e) where T : PCB_Node<T> {
这样的事情可能吗?
首先,您的class声明不正确。
你在这里说 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)
{
//...
}
}
如果在另一个 class 中声明了 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 中的静态 classes,但我猜你想要一个常规的 class.
要实现 IEnumerable,您可以使用 iterator block:
public IEnumerator<T> GetEnumerator()
{
yield return this
// add iteration logic
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
我个人会考虑将迭代器与 class 分开,因为可以用几种不同的方式迭代树。例如通过使用扩展方法:
public static IEnumerable<T> DepthFirst<T>(this PCB_Node<T> root) where T : PCB_Node<T>
{
yield return root;
// add iteration logic
}