林克类型检查3次-有更好的形状吗

本文关键字:更好 类型 检查 3次 林克 | 更新日期: 2023-09-27 17:58:04

我有一个Linq表达式,它对一个对象列表进行操作,在使用它之前,我需要键入其中一个对象属性进行检查。

示例:

IEnumerable<Employee> activeAuditOwners = (
    from objectStateEntry in objectStateEntries
    where ( objectStateEntry.Entity is IAuditEntity ) == true
       && ( objectStateEntry.Entity as IAuditEntity ).Active == true
    select ( objectStateEntry.Entity as IAuditEntity ).Owner
);

我担心的是,我使用了3次类型检查(is,as,as),感觉不是很枯燥。

对于这个查询,是否有更好的形状可以避免这种情况(不创建第二个查询)?

更新:感谢您的精彩回答,我为未来的读者整理了这个例子。

林克类型检查3次-有更好的形状吗

关于OfType扩展方法:

var data = from a in auditObjectStateEntries.OfType<IAuditEntity>()
           where a.Active
           select a.Owner;

编辑:

我忽略了实体部分,所以正确的查询是:

var data = from e in auditObjectStateEntries.Select(a => a.Entity).OfType<IAuditEntity>()
           where e.Active
           select e.Owner;

这里有一些不错的解决方案,但我会这样使用OfType

IEnumerable<Employee> activeAuditOwners = objectStateEntries
  .Select(s => s.Entity)
  .OfType<IAuditEntry>()
  ,Where(e => e.Active)
  .Select(e => e.Owner);

一种方法是使用let子句:

from auditObjectStateEntry in auditObjectStateEntries
let entity = auditObjectStateEntries.Entity as IAuditEntity
where entity != null
   && entity.Active
select entity.Owner

是的,您可以使用let表达式:

from auditObjectStateEntry in auditObjectStateEntries
let auditEntity = auditObjectStateEntry.Entity as IAuditEntry
where auditEntity != null
          &&
      auditEntry.Active
select auditEntry

更新:我忘记了其他回答者建议的OfType<T>。这绝对是一个更清洁的解决方案,所以建议使用这种方法。

首先,你可以忘记is,你不需要它

expression as type

相当于:

expression is type ? (type)expression : (type)null

因此,您可以通过使用一次转换尝试来简化代码,也许类似于以下内容:

IEnumerable<Employee> activeAuditOwners = (
    from auditObjectStateEntry in auditObjectStateEntries
    let entity = auditObjectStateEntry.Entity as IAuditEntry
    where entity != null && auditEntry.Active
    select auditEntry.Owner
);