【问题标题】:get specific properties within the generic list using linq使用 linq 获取通用列表中的特定属性
【发布时间】:2017-11-01 20:32:35
【问题描述】:

我有如下所示的通用列表 foo

var foo = new List<XYZ>();
public class XYZ
{
    public String TimeZone { get; set; }
    public Decimal? B1Volume { get; set; }
    public Decimal? B2Volume { get; set; }
    public Decimal? B3Volume { get; set; }
    public Decimal? B4Volume { get; set; }
    public Decimal? B5Volume { get; set; }
    // .............
    // .............
    public Decimal? B24Volume { get; set; }
    public String Name {get;set;}
}

如何选择属性B1Volume,........B24Volume ?

我尝试使用下面提到的以下代码,但它没有给出预期的结果

var hp = foo.Skip(1).Take(23).ToList();

【问题讨论】:

  • 当然没用。 Skip , Take ... 适用于对象而不是它们的属性。当您有这样的列表时,它可以工作:{xyz1, xyz2 .... xyz24}

标签: c# linq generic-list


【解决方案1】:

有几种方法,但我不认为你想走那条路。 你真的想要 xyz 的列表吗?或者以不同的方式问:你有很多不同的卷列表吗?还是您只想表达一个卷列表?

也许你想要做的是像这样在 XYZ 中声明一个数组

public class XYZ
{
    public String TimeZone { get; set; }
    public Decimal?[] Volumes {get; set;} = new Decimal?[24];
    public String Name {get; set;}
}

如果您想通过索引 (1,2,...,24) 访问卷,您需要一个数组或任何其他类型的索引数据结构。

那你就可以了

var xyz = new XYZ();
xyz.Volumes[0] = 12.0;
xyz.Volumes[1] = 23.0;
.....

基本上通过 xyz.Volumes 访问卷并添加索引以获得第 n 个卷

如果您现在想进一步列出这些 XYZ,您可以执行以下操作:

var listOfXyz = new List<XYZ>();
listOfXyz.Add(new XYZ());
....
listOfXyz[3].Volumes

这将为您提供列表中索引为 3 的元素的 24 卷。

【讨论】:

    【解决方案2】:

    你需要做一个Select:

    var hp = foo.Select(x => new { x.BVolume1, x.BVolume2, ..., x.BVolume24 });
    

    虽然我同意@Himzo 的观点,但如果您可以更改结构,这不是解决问题的最佳方法。

    【讨论】:

      【解决方案3】:

      也许有帮助:

      XYZ xyz = new XYZ();
      Type t = xyz.GetType();
      List<PropertyInfo> properties = new List<PropertyInfo>(t.GetProperties());
      var hp = properties.Skip(1).Take(23).ToList();
      

      不要忘记添加名称空间:

      using System.Reflection;
      

      更新

      在 cmets GBreen12 中建议添加一个过滤器以仅获取名称包含 volume 的属性。现在,如果您添加其他属性,代码将不会失败。所以你可以把第 3 行改成这样:

      List<PropertyInfo> properties = (new List<PropertyInfo>(t.GetProperties())).Where(x => x.Name.EndsWith("Volume")).ToList();
      

      现在您不需要最后一行var hp = ...properties 就是您的答案。

      【讨论】:

      • 我建议不要假设来自GetProperties 的返回与声明的顺序相同(尽管当前编译器就是这种情况)并过滤属性名称。
      • @NetMage 我测试了确切的类XYZ 并且属性顺序相同。
      • @FarzinKanzi 我认为 NetMage 想说的是,由于各种原因,假设属性的顺序并不安全。即使现在它们以正确的顺序返回,对象定义也可能以多种方式改变,这会搞砸。
      • @GBreen12 谢谢。你的意思是对象定义可以以多种方式改变
      • 我觉得如果你打算这样做,你应该做某种Where,比如.Where(x =&gt; x.Name.EndsWith("Volume"))。在这种情况下,您不需要 SkipTake
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多