gpt4 book ai didi

c# - Linq-InvalidCastException-为什么“where”不过滤无效类型

转载 作者:太空宇宙 更新时间:2023-11-03 17:35:50 25 4
gpt4 key购买 nike

在复杂的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"; }
}


第一个转储工作正常并返回:

extendedproperty baseproperty type 1                1            A1.1              2            B1                3            A

However the second Dump errors with:

InInvalidCastException: Unable to cast object of type 'typeB' to type 'typeA'.

I can fix this by just removing the "typeA" but I wouldn't want to do that in the original statement as I would have to cast the type all over the place:

from item in items


有趣的是,尽管您可能认为这有点丑陋,但将其移动到哪里也可以解决此问题:

from typeA item in items.Where(i => i is typeA)


我的问题是:为什么原始对象在评估转换之前不过滤掉无效项?

最佳答案

原因1:

对类型的强制转换发生在过滤器之前,因为它位于左侧。在C#中,几乎总是发生以下情况:左边的事物发生在右边的事物之前。

原因2:

假设我们按照您的方式做了。您有一个List<object>,您说

from string s in myObjects where s.Length > 100


并且您会收到一个错误消息,说该对象没有Length属性-因为按照您的方式,对字符串的强制转换发生在过滤器之后,因此过滤器不能依赖于由强制转换确定的不变式。大概是因为您要使用目标类型的属性,所以将转换放在了那里。但是,你不能同时兼顾。左操作先运行,或者右操作先运行。他们不能都先运行。

原因3:

已经有一种方法可以执行您想要的操作:

... from foos.OfType<Bar>() ...


这相当于先过滤,然后仅提供正确类型的已过滤值的序列。

关于c# - Linq-InvalidCastException-为什么“where”不过滤无效类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3339038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com