在复杂的linq查询中有问题所以我在LINQPad中简化了它:
void Main()
{
List<basetype> items = new List<basetype>()
{
new typeA() { baseproperty = "1", extendedproperty = 1 },
new typeB() { baseproperty = "2", extendedproperty = 1.1 },
new typeA() { baseproperty = "3", extendedproperty = 1 },
};
items.Dump();
(from typeA item in items
where item is typeA
select item).Dump();
}
public abstract class basetype
{
public string baseproperty { get; set; }
public string type { get; set; }
}
public class typeA : basetype
{
public int extendedproperty { get; set; }
public typeA() { type = "A"; }
}
public class typeB : basetype
{
public double extendedproperty { get; set; }
public typeB() { type = "B"; }
}
Run Code Online (Sandbox Code Playgroud)
第一个转储工作正常并返回:
extendedproperty baseproperty type 1 1 A 1.1 2 B 1 3 A
但是第二个转储错误:
InInvalidCastException: Unable to cast object of type 'typeB' to type 'typeA'.
我可以通过删除"typeA"来解决这个问题,但我不想在原始语句中这样做,因为我必须在整个地方强制转换类型:
from item in items
Run Code Online (Sandbox Code Playgroud)
有趣的是,移动地点也修复了这个问题虽然你可能会认为有点难看:
from typeA item in items.Where(i => i is typeA)
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么是原来的地方投评估之前不会过滤掉不合理的项目?
Eri*_*ert 10
理由#1:
对类型的强制转换发生在过滤器之前,因为它出现在左侧.在C#中,左边的东西几乎总是出现在右边的东西之前.
理由#2:
假设我们按照你的方式做到了.你有一个List<object>,你说
from string s in myObjects where s.Length > 100
Run Code Online (Sandbox Code Playgroud)
并且你得到一个错误,说该对象没有Length属性 - 因为当然按照你的方式在过滤器后发生转换为字符串,因此过滤器不能依赖于强制转换所确定的不变量.大概是你把演员放在那里因为你想使用目标类型的属性.但你不可能两种方式; 左操作先运行或右操作先运行.他们不能先跑.
原因#3:
已经有办法做你想做的事:
... from foos.OfType<Bar>() ...
Run Code Online (Sandbox Code Playgroud)
这相当于先过滤然后提供一个只有正确类型的过滤值的序列.
| 归档时间: |
|
| 查看次数: |
606 次 |
| 最近记录: |