【问题标题】:Linq to Objects where clause and typecastingLinq to Objects where 子句和类型转换
【发布时间】:2012-03-16 07:40:01
【问题描述】:

我有以下几点:

class BaseType {
  public Int32 Id { get; set; }
}

class Option : BaseType {
  public String DisplayName { get; set; }
  public String StoredValue { get; set; }
}

class Container {
  public Collection<BaseType> Options;
}


Container c = new Container();
c.Options.add(new Option() { Id=1, DisplayName="Bob", StoredValue="aaaa"});
c.Options.add(new Option() { Id=2, DisplayName="Dora", StoredValue="bbbb"});
c.Options.add(new Option() { Id=3, DisplayName="Sara", StoredValue="cccc"});

现在,我要做的是提取与 StoredValue 匹配的特定选项的 DisplayName。

以前,我会遍历整个集合,直到找到匹配项。但是,我宁愿有一些看起来更好的东西......

我开始了

var found = (from c in c.Options
             where ...

这就是我卡住的地方。

【问题讨论】:

    标签: c# linq-to-objects


    【解决方案1】:

    我认为这就是您想要的:(如果找到 0 个或多于 1 个匹配项,Single 将出错)

    string searchValue = "aaaa";
    string displayName = c.Options.OfType<Option>.Single(o => o.StoredValue == searchValue).DisplayName;
    

    或允许多个值:(这将为您提供所有匹配的显示名称,从 0 到多个)

    IEnumerable<string> displayNames = from o in c.Options.OfType<Option>
                                       where o.StoredValue == searchValue
                                       select o.DisplayName;
    

    【讨论】:

    • 哦,现在我明白为什么它首先让您感到困惑了!我已经使用OfType 扩展修复了代码,它将选项列表过滤为Option 类型,而无需您为其编写逻辑(并像其他答案一样引入错误)。
    【解决方案2】:

    应该这样做:

    c.Options.OfType<Option>()
     .Where(o => o.StoredValue == "aaaa")
     .Select(o => o.DisplayName)
     .SingleOrDefault();  //or .ToList() 
    

    【讨论】:

    • 这是一个糟糕的答案,如果你有任何其他类型,它会爆炸。
    • @CrazyDart:没有什么是简单的检查解决不了的,就像现在添加到代码中一样。
    • 检查没问题(并且有效),但你只是在你的 lambas 中重新实现了 OfType -- 两次。
    【解决方案3】:
    var found = (from c in c.Options.OfType<Option>()
                 where c.StoredValue == yourValue
                 select c.DisplayName).FirstOrDefault();
    

    【讨论】:

      【解决方案4】:

      这是使用 Linqpad。您需要先转换为 Option 类型,然后才能使用它。我进行了检查以查找所有该类型,然后检查值。

      void Main()
      {
          Container c = new Container();
          c.Options.Add(new Option() { Id=1, DisplayName="Bob", StoredValue="aaaa"});
          c.Options.Add(new Option() { Id=2, DisplayName="Dora", StoredValue="bbbb"});
          c.Options.Add(new Option() { Id=3, DisplayName="Sara", StoredValue="cccc"});
      
      var t = from x in c.Options.OfType<Option>()
              where x.DisplayName == "Bob"
              select x.StoredValue;
      t.Dump();
      
      }
      
      class BaseType {
        public Int32 Id { get; set; }
      }
      
      class Option : BaseType {
        public String DisplayName { get; set; }
        public String StoredValue { get; set; }
      }
      
      class Container {
        public List<BaseType> Options;
      
        public Container() { Options = new List<BaseType>(); }
      }
      

      【讨论】:

      • 我无法将容器选项更改为使用列表。当我尝试这个时,它在 .OfType
      • 有趣,因为它在我的系统上运行得很好。
      • 好的,所以我在一个新项目中尝试了这个确切的代码并且有效。不知道为什么我在实际项目中得到 .OfType 下的波浪线。很有趣。
      • 找出问题所在。我显然无法正确阅读括号。在 .OfType 之后我错过了它们
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多