【问题标题】:How to cast while Sorting?排序时如何投射?
【发布时间】:2013-02-18 14:36:39
【问题描述】:

我有类 Vehicleclass:Car 继承自 class:Vehicle,如下所示。我有一个列表,我想使用 LINQ 根据 Car 类(不是车辆父类)的属性对其进行排序。

class vehicle
{
    public String Name {get; set; }
}

class Car:Vehicle
{
    public String ModelName {get; set; }
}

List<Vehicle> vehicleList=new List<Vehicle>();

Car c1 = new Car();
vechicleList.Add(c1); //s note that i am adding **Car** objects

Car c2 = new Car();
vechicleList.Add(c2);
// added 10 such Car objects

然后我想根据 CarModel 对车辆列表进行排序(这是 Car 的属性,而不是 Parent 类的属性)

我尝试了下面的方法,但它不起作用。

vehicleList.OrderBy(c => (Car)c.ModelName)

关于如何做到这一点的任何帮助?

【问题讨论】:

  • 如果需要List&lt;Car&gt;,为什么还要使用List&lt;Vehicle&gt;
  • @TimSchmelter 我正在处理一些遗留代码。并且有限制改变.. :(

标签: c# .net linq sql-order-by


【解决方案1】:

你必须决定你想要什么:

Car 实例列表或Vehicle 实例列表。

如果您想获得Vehicle 实例的列表,则不能按Car 的属性排序,因为在Vehicles 列表中也可能有BusBicycle。 执行您当前尝试的操作(强制转换为 Car)可能会在运行时引发异常。

话虽如此,如果你坚持这样做,你必须注意两件事:

  1. 你需要修复你的演员:vehicleList.OrderBy(c =&gt; ((Car)c).ModelName)
  2. 您需要注意OrderBy 不会执行就地排序。 vehicleList 仍将保持原来的顺序。如果要在vehicleList 中得到排序结果,则需要将OrderBy 的结果分配给它:

    vehicleList = vehicleList.OrderBy(c => ((Car)c).ModelName).ToList();
    

【讨论】:

  • 如果我的列表只包含汽车并且演员不会失败怎么办?
  • @user2025418 如果您的列表只包含Car 对象,那么它首先应该是List&lt;Car&gt;,而不是List&lt; Vehicle &gt;
  • @Servy 是的,这是有道理的,但我正在尝试使用遗留代码,它有一个列表....改变它需要很多努力
【解决方案2】:

做你想做的最易读的代码是

vehicleList.Cast<Car>().OrderBy(c => c.ModelName);

当然你也可以修复括号并写成相同的

vehicleList.OrderBy(c => ((Car)c).ModelName);

也就是说,如果您的列表中有任何 Vehicle 不是 Car,那么上述两种情况都会崩溃。如果这不能发生,那为什么首先不是List&lt;Car&gt;

【讨论】:

  • 如果车辆列表中包含飞机怎么办?
  • OfType() 在这种情况下是安全的 PS:我总是会在评论 8 之前更新)
  • 谢谢,这对我有用。我正在对其他人的代码进行一些小修改,并且可以保证只有 Car 对象存在。我去 Linq 排序它是 Orderby()ThenBy 的一个例子。再次感谢!
【解决方案3】:

您必须将c 转换为Car,而不是c.ModelName

试试:

vehicleList.OrderBy(c => ((Car)c).ModelName)

【讨论】:

  • 但是如果你在 vehicleList 中有一个Truck 会失败:( +1 虽然
  • 当然会。 Jon 和 Daniel Hilgarth 提供了更多细节。感谢您的支持 :) 请注意,使用 OfType&lt;Car&gt; 不会失败,但会改变语句的含义,因为它不会处理所有车辆。这绝对应该是 List&lt;Car&gt; 以确保正确的行为。
【解决方案4】:

尝试使用:

vehicleList.OfType<Car>().OrderBy(c=>c.ModelName)

注意: 这只会返回您列表中的汽车

【讨论】:

    【解决方案5】:
    vehicleList.OfType<Car>().OrderBy(c=>c.ModelName)
    

    【讨论】:

    • 这和写.OfType&lt;Car&gt;()一样,只是更健谈。
    【解决方案6】:

    试试这个:

    vehicleList.OrderBy(c=>((Car)c).ModelName)
    

    但要注意,如果物品实际上不是汽车,它会爆炸!

    解决方法是:

    vehicleList.OrderBy<Vehicle, string>(c=>
    {
        Car car = c as Car;
        if (car != null)
            return car.ModelName
        else
            return "";
    }
    

    但如果有“非汽车”,则位置将由空字符串相对于列表中的其他项目确定。

    【讨论】:

    • 这看起来很有趣!那我可以写下面这样的东西吗? vehicleList.OrderBy(c=> { Car car = c as Car; if (car != null) return car.ModelName; else if (c is plane) return plane.planeNumber; }
    • 它给出了错误:方法'System.Linq.Enumerable.OrderBy的类型参数(System.Collections.Generic.IEnumerable, System.Func)' 不能从用法中推断出来。尝试明确指定类型参数。
    猜你喜欢
    • 2017-02-09
    • 2020-11-18
    • 2017-03-17
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多