你如何在 C# 中投射我列表?

  • 本文关键字:列表 c# list base-class
  • 更新时间 :
  • 英文 :


我正在尝试投射一个列表。

public class Base
{
}
public class Item: Base
{
}

然后在另一个类中,我有属性请求列表1

public List<Base> requestList1{ get; set; }

尝试:

requestList1 = form.item.Cast<Item>()
requestList1  = new List<Item>(form.item)

错误 CS0266 无法隐式转换类型 'System.Collections.Generic.IEnumerable' to "System.Collections.Generic.List"。存在显式转换 (你缺少演员表吗?

您不能直接将它们相互投射。考虑以下情况:

public class Base
{
}
public class Item: Base
{
}
public class EvilItem: Base
{
}

所以让我们尝试从List<Item>投射到List<Base>

List<Item> a = new List<Item>();
List<Base> b = (List<Base>)a;
b.Add(new EvilItem());

啊,我们有一个问题。由于List<T>是引用类型,因此ab现在都是对同一列表的引用。我们只是在List<Item>中添加了一个EvilItem- 这是不应该允许的。但是b.Add(new EvilItem());线是完全合法的,因为b是一个List<Base>.

这也是相反的。如果你创建了一个List<Base>那么你就不能把它投射到List<Item>,因为其中的某些项目可能会EvilItem。或者也许它们稍后会被添加。

因此,.NET 禁止此类强制转换。

您有几个选择。首先,您可以创建列表的副本:

b = new List<Base>(a);

现在ab是两个完全不同的列表,恰好具有相同的内容。请记住,更改一个列表不会更改另一个列表。

或者,如果不需要修改列表,则可以将其用作枚举对象:

IEnumerable<Base> c = a;

为什么这有点长,但为了简化它 -IEnumerable只允许您阅读列表,因此您不能做诸如添加EvilItem之类的坏事。因此,这是允许的。

至于为什么requestList1 = form.item.Cast<Item>()不起作用 -Cast<T>()产生IEnumerable<T>,而不是List<T>,所以你不能分配它。您可以将其更改为requestList1 = form.item.Cast<Base>().ToList(),这将起作用 - 但它也会复制列表。实际上,这是另一种方法,尽管编写时间有点长,而且我也怀疑它的效率有点低(但我没有证据(

最新更新