java - 如何将这段 C# 泛型转换为 Java

标签 java c# generics

给定以下 C# 代码,如何将其转换为 Java?

public class Stop : IComparable<Stop>
{
    public int CompareTo(Stop other) { ... }
}

public class Sequence<T> : IEnumerable<T>
    where T : IComparable<T>
{
    public IEnumerator<T> GetEnumerator() { ... }

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

public class Line<T> : Sequence<T>, IComparable<Line<T>>
    where T : Stop
{
    public int CompareTo(Line<T> other) { ... }
}

我在将类 Line 的定义翻译为 Java 时遇到了困难。我的第一次尝试如下:

public class Line<T extends Stop> extends Sequence<T> implements Comparable<Line<T>> { ... }

但是,编译器报告 extends Sequence<T> 的以下错误:

Error: type argument T is not within bounds of type-variable T

将定义更改为

public class Line<T extends Comparable<T>> extends Sequence<T> implements Comparable<Line<T>> { ... }

修复了错误,但没有准确反射(reflect)意图:我想强制与 Line 一起使用的所有类型参数必须是 Stop 的子类型。使用T extends Comparable<T>将允许实现该接口(interface)的任意类型。

我不明白错误的原因。有没有某种方法可以在不改变类型结构的情况下表达这种关系,或者这是 Java 泛型的限制吗?

编辑:访问https://www.onlinegdb.com/S1u9wclnH查看我的尝试的精简版本。

最佳答案

问题是你对 class Sequence 的定义.

public class Sequence<T> : IEnumerable<T>
    where T : IComparable<T> { ... }

这个 C# 类利用 IComparable 的事实是逆变的,因此 C# 类不需要完全 T: IComparable<T> ,但如果T也很高兴与其基类之一相当。因此,即使 T ,代码也能工作。使用派生自 Stop 的类进行实例化.

Java 没有声明站点差异,但有使用站点差异(通配符)。你的Java Sequence无法为从 Stop 派生的类实例化该类,但是你的Line类可能是。因此编译器错误。

要解决此问题,每当您使用 Comparable 时,您都需要将 C# 的声明站点差异转换为 Java 的通配符在范围内:

class Sequence<T extends Comparable<? super T>> implements Iterable<T> { ... }

关于java - 如何将这段 C# 泛型转换为 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58902790/

相关文章:

java - 为什么这些在 Java 中无效?

java - 如何截断 java 整数以适应/扩展到给定的字节数?

java - 无法测试神经网络的收敛性

c# - 配置错误 - 调用目标已引发异常

c# - 在简单注入(inject)器中调用拦截的方法调用上的函数

java.lang.ClassNotFoundException : com. twilio.type.Endpoint tomcat 问题

c# - C# 中字符串的 OR 操作数

java - 我如何将参数作为通用参数传递?

Java : What is - public static<T> foo() {. ..}?

java - 使用类级别(如通用有界类型参数)作为方法的形式参数