[英]Why can't I cast from a List<MyClass> to List<object>?
我有一个对象列表,它们属于我的QuoteHeader
类型,我想将此列表作为对象列表传递给能够接受List<object>
的方法。
我的代码行显示...
Tools.MyMethod((List<object>)MyListOfQuoteHeaders);
但是我在设计时收到以下错误...
Cannot convert type 'System.Collections.Generic.List<MyNameSpace.QuoteHeader>'
to 'System.Collections.Generic.List<object>'
我需要对我的 class 做任何事情来允许这样做吗? 我认为所有类都继承自 object 所以我不明白为什么这不起作用?
这不合法的原因是因为它不安全。 假设它是合法的:
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes; // this is not legal; suppose it were.
animals.Add(new Tiger()); // it is always legal to put a tiger in a list of animals
但“动物”实际上是长颈鹿的列表; 你不能把老虎放在长颈鹿的名单上。
不幸的是,在 C# 中,这对于引用类型的 arrays 是合法的:
Giraffe[] giraffes = new Giraffe[10];
Animal[] animals = giraffes; // legal! But dangerous because...
animals[0] = new Tiger(); // ...this fails at runtime!
在 C# 4 中,这在IEnumerable但不是IList上是合法的:
List<Giraffe> giraffes = new List<Giraffe>();
IEnumerable<Animal> animals = giraffes; // Legal in C# 4
foreach(Animal animal in animals) { } // Every giraffe is an animal, so this is safe
这是安全的,因为IEnumerable<T>
不公开任何接受T 的方法。
要解决您的问题,您可以:
List<object>
,并使用不安全的数组协方差。List<T>
IEnumerable<object>
并使用 C# 4。 您不能将List<OneType>
转换为List<OtherType>
因为它实际上是您要转换的列表的实例,以及 List 本身。
有一种扩展方法可以让您执行此操作( MSDN 参考):
IEnumerable<Object> myNewEnumerable = myEnumerable.Cast<Object>();
此方法将尝试将一种类型列表的每个实例转换为另一种类型,并将它们添加到新的可枚举中。 如果无法转换任何实例,它将引发异常。
就系统而言,您的列表的两种类型只是不同的类型,所以就像说:
A objectOfTypeA;
B objectOfTypeB = (B) objectofTypeA;
为了能够进行强制转换,必须在可用类型之间进行隐式或显式转换,而这是不存在的(除非您提供了一个,您可能可以这样做)。
您希望它能够工作,因为List<object>
将始终能够在另一个列表中保存任何类型,但是当您以这些术语考虑它时,您会明白为什么它不能。
我确信有一个技术上更胜任的答案,但我认为这就是它的要点。
您可能有兴趣阅读Eric Lippert 关于协变和逆变的系列文章,因为这可能对您有所帮助。
这个问题也可能有用
List<MyClass> x = someList.Select(f => (MyClass)f).ToList();
我假设您的意思是列表是相互继承的类型,或者可以从一种类型转换为另一种类型 - 在这种情况下,试试这个:
Tools.MyMethod(MyListOfQuoteHeaders.Cast<OtherType>());
感谢您的许多回复。
我将解释我想做什么以及我想出的解决方案。
我需要一个方法,我可以通过传入任何类型的对象列表然后将 output 传递给 XML 来调用该方法。 传递给该方法的还有一个字符串,它将是一个系统文件结构路径位置,它指向 XML 文件将保存到的位置。 由于我有越来越多的类和类型,我想避免编写多种方法来满足每种类型的 class。 我不确定我是否以正确的方式解决了这个问题,但它是解决我的问题并且有效的轻量级解决方案。 如果有任何问题,或者如果任何人有任何意见,请随时...
所以......我的方法现在看起来像这样......
public static Enums.Status WriteListToXML<T>(string outputPath, List<T> inboundList)
{
try
{
XmlSerializer xmlSerializer = new XmlSerializer(inboundList.GetType());
using (StreamWriter streamWriter = System.IO.File.CreateText(outputPath))
{
xmlSerializer.Serialize(streamWriter, inboundList);
}
return Enums.Status.Success;
}
catch (Exception ex)
{
return Enums.Status.Failure;
}
}
...而我的电话号码是...
WriteListToXML<QuoteHeader>(@"C:\XMLDocuments\output\QuoteHeaders.xml", quoteHeadersList);
就像我说的,它可能不是最整洁的解决方案,但在我的场景中效果很好。
问题是在编译时,编译器发出 2 个单独的类,1 个代表List<MyClass>
,一个代表List<Object>
。 它们本质上是两种不同的类型。 这就是通用类型的工作方式,至少在.Net 中是这样。
假设这是.Net,你可以做
MyListOfQuoteHeaders.Cast<Object>()
基本上可以
var objects = new List<Object>();
foreach(var item in MyListOfQuoteHeaders)
{
objects.Add((object)item);
}
return objects;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.