我有一个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),感觉不是很枯燥。
对于这个查询,是否有更好的形状可以避免这种情况(不创建第二个查询)?
更新:感谢您的精彩回答,我为未来的读者整理了这个例子。
关于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
);