c# - Java 增强的 for 循环 VS .NET foreach 循环

标签 c# java polymorphism foreach

我有一个问题,我还没有找到答案。 假设我们在 java 或 c# 中有以下代码:

class Car {
   /* car stuff */
}

然后在 Java 中

class Truck extends Car {
   /* truck stuff */
}

和 C#

class Truck : Car {
   /* truck stuff again */
}

在 C# 中,以下工作正常:

List<Car> carList = new List<Car>();
//add some objects to the collection
foreach(Truck t in carList)
     //do stuff with only the Truck objects in the carList collection

之所以可行,是因为 Truck 是 Car 的子类,简单来说,这意味着每辆 Truck 也是一辆 Car。问题是,类型检查已经完成,并且只从 carList 中选择了卡车。

如果我们在 Java 中尝试同样的事情:

List<Car> carList = new ArrayList<Car>();
//add some objects to the collection
for(Truck t : carList)
     //**PROBLEM**

由于增强循环中的代码,代码甚至无法编译。相反,我们必须做这样的事情才能获得相同的效果:

for(Car t : carList)
   if(t instanceof Car)
      //cast t to Truck and do truck stuff with it

这与在 C# 中工作没有任何问题的想法相同,但在 Java 中您需要额外的代码。连语法都几乎一样! 它在 Java 中不起作用有什么原因吗?

最佳答案

The thing is though, that type checking is done and only Trucks are selected from carList.

不,不是。如果您的列表包含除 Truck 之外的任何内容s,在C#中会出现运行时异常。基本上,在 C# 中,如下

foreach(Truck t in carList) {
    ...
}

表现得像

foreach(object _t in carList) {
    Truck t = (Truck)_t;        // throws an InvalidCastException if _t is not a Truck
    ...
}

另一方面,Java 变体是类型安全的:您必须自己进行转换和类型检查。


那么,为什么 Java 和 C# 的行为不同?这是我的猜测:

C# 有 foreach关键字在它有泛型之前。因此,不可能有List<Car>。 .如果 C# 选择了 foreach 的 Java 方式,你必须写

foreach(object _c in myArraylistContainingOnlyCars) {
    Car c = (Car)_c;
    // do something with c
}

这很烦人。另一方面,扩展的 for 循环和泛型是在同一版本(Java 5)的 Java 中引入的,因此不需要自动转换。

关于c# - Java 增强的 for 循环 VS .NET foreach 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10101635/

相关文章:

java - hibernate 唯一 key 验证

c++ - 转换持有多态类型的模板时的未定义行为

c# - 如何获取所选壁纸的名称

c# - 使用 Regex 将带引号的字符串与嵌入的非转义引号匹配

c# - 绑定(bind)到 BindingList 的 DataGridView 在值更改时不刷新

java - 用正则表达式模式替换字符串部分

java - 解析xml找到根标签,然后将标签附加到根标签下

c# - HttpContext.Current.Request.QueryString 解码不正确 §

Java - 具有相同方法的不同对象的数组

Java 实例与抽象类和方法