我正在尝试投射一个列表。
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>
是引用类型,因此a
和b
现在都是对同一列表的引用。我们只是在List<Item>
中添加了一个EvilItem
- 这是不应该允许的。但是b.Add(new EvilItem());
线是完全合法的,因为b
是一个List<Base>
.
这也是相反的。如果你创建了一个List<Base>
那么你就不能把它投射到List<Item>
,因为其中的某些项目可能会EvilItem
。或者也许它们稍后会被添加。
因此,.NET 禁止此类强制转换。
您有几个选择。首先,您可以创建列表的副本:
b = new List<Base>(a);
现在a
和b
是两个完全不同的列表,恰好具有相同的内容。请记住,更改一个列表不会更改另一个列表。
或者,如果不需要修改列表,则可以将其用作枚举对象:
IEnumerable<Base> c = a;
为什么这有点长,但为了简化它 -IEnumerable
只允许您阅读列表,因此您不能做诸如添加EvilItem
之类的坏事。因此,这是允许的。
至于为什么requestList1 = form.item.Cast<Item>()
不起作用 -Cast<T>()
产生IEnumerable<T>
,而不是List<T>
,所以你不能分配它。您可以将其更改为requestList1 = form.item.Cast<Base>().ToList()
,这将起作用 - 但它也会复制列表。实际上,这是另一种方法,尽管编写时间有点长,而且我也怀疑它的效率有点低(但我没有证据(