我有一个类型对象的集合,我知道它们是类型Employee。我想对员工执行一些linq操作,使用类似的东西:
var options = (from e in m_Employees
select (e as Employee).DepartmentCode).Distinct();
但是,作为员工,出错并不奇怪。有办法吗?
更改集合并不是一个真正的选择,因为我维护代码并且我想避免重大更改。
答案 0 :(得分:9)
您可以使用
from e in m_Employees.Cast<Employee>()
select e.DepartmentCode
或
from e in m_Employees.OfType<Employee>()
select e.DepartmentCode
如果您无法将每个项目投放到Cast
,则 Employee
会出错,但OfType
会过滤掉与该类型不匹配的对象。
答案 1 :(得分:6)
最好不要使用as Employee
,而是让编译器基本上使用显式类型的范围变量插入对Cast<T>
的调用:
var options = (from Employee e in m_Employees
select e.DepartmentCode).Distinct();
或者等同地:
var options = m_Employees.Cast<Employee>()
.Select(e => e.DepartmentCode)
.Disinct();
但是,如果数组真的 仅包含Employee
引用,我仍然不会期望你的原始代码失败...如果你得到{{1}然后要么其中一个值为null,或它是对非Employee对象的非空引用。上述代码仍然会给您一个错误,但您可以根据您是否仍然获得NullReferenceException
或NullReferenceException
来查看哪一个。
一般情况下,只有在有条件地使用结果时才应使用InvalidCastException
。如果你确定每个值都是正确的类型,你应该使用强制转换 - 这样如果你错了,你会得到一个异常的代码,而不是将空引用传播到代码的其余部分,以后可能会造成伤害,并且很难发现错误的来源。
如果您遇到编译时错误,那么根据您看到的异常情况,可能会有多种原因。
编辑:好的,导致编译时错误的as
... IEnumerable
和Cast<T>()
都是OfType<T>()
上的扩展方法,而不是IEnumerable
。
答案 2 :(得分:0)
一种选择是:
(from e in m_Employees
let x = e as Employee
select x.DepartmentCode).Distinct();
答案 3 :(得分:0)
使用此:
var options = (from e in m_Employees.Cast<Employee>()
select e.DepartmentCode).Distinct();
重要的部分是Cast<Employee>
。我的回答是假设m_Employees
是IEnumerable
ArrayList
而不是IEnumerable<Employee>
,而不是List<Employee>
。
答案 4 :(得分:0)
你可以试试这个:
var options = m_Employees
.Cast<Employee>()
.Select(item => item.DepartmentCode)
.Distinct();