【问题标题】:Sort dynamic List<T> for a specific property为特定属性排序动态 List<T>
【发布时间】:2016-08-19 04:29:57
【问题描述】:

我有一个通用列表,我想按两个属性排序,优先级然后按描述来填充下拉列表。

我知道当我现在完全可以做对象列表的类型时

list = list.Orderby(x=>x.property1).ThenOrderBy(x=>x.property2).

我的问题是如何检查对象上是否存在 property1 和 property2,然后根据这些属性对我的列表进行排序。

【问题讨论】:

  • 如果这些属性属于接口或类,您可以对 T 使用约束
  • 编译器会为你做这件事。如果它们不存在,编译将失败。
  • 你的意思是List&lt;dynamic&gt;
  • 是的,我的意思是列表
  • 你无法在编译时知道。 dynamic 将所有类型检查移至运行时。如果底层类型具有这些属性,你会采取什么不同的做法?

标签: c# linq list generics


【解决方案1】:

因为您使用的是通用列表,所以编译器会为您检查。

例如:如果你写这样的代码

List<Object> list = new List<Object>();
var newlist = list.Orderby(x=>x.property1).ThenOrderBy(x=>x.property2);

您将在 property1 和 property2 上收到编译器错误,因为编译器不会在 Object 类型上找到这些属性。

如果您想支持每个都应该具有这 2 个属性的不同类型,正确的方法是使用这 2 个属性创建一个接口,让您想要支持的每个类型实现该接口,然后对T 喜欢 Arturo 提出的建议。

类似

interface ICanBeSorted
{
   string property1 {get;}
   string property2 {get;
}

public List<T> MySortMethod(List<T> list) where T : ICanBeSorted
{
   return list.OrderBy(x=>x.property1).ThenOrderBy(x=>x.property2);
}

此方法将能够对所有实现接口 ICanBeSorted 的类型进行排序。

【讨论】:

    【解决方案2】:

    您可以将选择器包装在 try-catch 块中:

    Func<dynamic, dynamic> DynamicProperty(Func<dynamic, dynamic> selector)
    {
        return x =>
        {
            try
            {           
                return selector(x);
            }
            catch (RuntimeBinderException)
            {
                return null;
            }
        };
    }
    

    用法:

    var sorted = list
        .OrderBy(DynamicProperty(x => x.property1))
        .ThenBy(DynamicProperty(x => x.property2));
    

    【讨论】:

      【解决方案3】:

      好吧,您尝试这样做的方式是个坏主意。尝试先使用 if-else 或 switch case,然后将您的代码按照您想要的方式进行排序。

      【讨论】:

        猜你喜欢
        • 2021-05-25
        • 2019-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-20
        • 2023-04-10
        • 1970-01-01
        相关资源
        最近更新 更多