代码之家  ›  专栏  ›  技术社区  ›  Daniele Sartori

当所有对象都是不同类型的EventArgs时,如何从List<Object>获取特定项

  •  1
  • Daniele Sartori  · 技术社区  · 5 年前

    我有一个叫 eventQueue 其中我存储了后台执行的任务生成的所有事件。现在,我需要处理从中提取特定事件的列表。我想使用LINQ主要是为了代码的可读性(我不想写多个foreach),我的问题是我不知道如何继续。假设我有一个自定义的多个实例 EventArgs 命名 FirstEventArgs 我想从列表中提取一个特定的,做一个我要写的foreach

    foreach(object o in eventQueue)
    {
       if( o is FirstEventArgs)
       {
           FirstEventArgs ev = o as FirstEventArgs ;
           if( ev.MyProperty == desiredValue)
           {
              // you got it 
           }
       }
    }
    

    目前我能用linq写下以下内容

    FirstEventArgs ev = eventQueue.Where(x => x.GetType() == typeof(FirstEventArgs )).SingleOrDefault() as FirstEventArgs;
    

    我的问题是。如何修改前一个以添加条件 ev.MyProperty = desiredValue 如果x是object类型,在何处?

    1 回复  |  直到 5 年前
        1
  •  2
  •   Slappywag    5 年前

    你可以使用 && 运算符,然后强制转换为所需类型。只有当前半部分为真时,才会对and语句的后半部分进行计算,因此您不会从强制转换中得到任何错误。这就是所谓的短路评估,根据这个答案( Is relying on && short-circuiting safe in .NET? )可在C中使用。

    FirstEventArgs ev = eventQueue.Where(x => x.GetType() == typeof(FirstEventArgs) 
                                           && ((FirstEventArgs)x).MyProperty == desiredValue)
                                  .SingleOrDefault() as FirstEventArgs;
    
        2
  •  3
  •   mmathis    5 年前

    可以在LINQ查询中使用模式匹配将对象强制转换为类型:

    FirstEventArgs ev = eventQueue.Where(x => x is FirstEventArgs fea && fea.MyProperty == desiredValue)
                                  .SingleOrDefault() as FirstEventArgs;
    

    感谢@slappywag检查它是否有效!

        3
  •  1
  •   Damien_The_Unbeliever    5 年前

    OfType 允许您进行类型测试并免费抛出强制转换:

    FirstEventArgs ev = eventQueue
                         .OfType<FirstEventArgs>()
                         .SingleOrDefault(fea=>fea.MyProperty==desiredValue);
    

    (我还将剩余的过滤移到 SingleOrDefault 打电话是因为,为什么不?)

    是的,其他的答案也有效,但我觉得“机制”还是有点太多了,而不仅仅是声明 我们想要什么 .