【问题标题】:Downcasting Lists [duplicate]向下转换列表 [重复]
【发布时间】:2011-03-01 11:19:57
【问题描述】:

可能重复:
In C#, why can't a List<string> object be stored in a List<object> variable

假设您有一个类,它通过不同类的集合触发事件。您想要获取这些集合并实例化一个对象,该对象将 List 作为其构造函数的参数(您需要 IList 的方法:索引访问,indexOf 等)。

最佳做法是什么?

如果事件返​​回 List 或 IList,您必须在从更具体的类的 List 创建它时进行一些讨厌的转换,比如 List 因为 IList 是不变的。

new DataObject(someClasses.Cast<object>().ToList())

您可以在事件中使用 Enumerable,然后至少您可以简单地执行 new DataObject(someClasses.ToList()) 但仍然必须创建一个新的列表,这可能会产生一些开销......

Lists 不能自动向下转换为对象似乎有点奇怪

【问题讨论】:

  • 标记为重复,但你考虑过非泛型IList接口吗?
  • 是的,这可能是一个解决方案,谢谢。不过,现在使用非泛型接口有点伤人 :)

标签: c# .net generics covariance


【解决方案1】:

问题在于您的方法将List&lt;object&gt; 作为参数。选项:

  • 让他们接受IEnumerable&lt;object&gt;
  • 使它们通用,采用List&lt;T&gt;

这就是为什么你不能将List&lt;string&gt; 转换为List&lt;object&gt; 的原因:

List<string> strings = new List<string>();
List<object> objects = strings;
objects.Add(new Button());
string text = strings[0];

显然,它不能在执行时“工作”,所以最好在编译时禁止它。第 1 行、第 3 行和第 4 行对我来说都很好 - 所以 got 是第 2 行导致问题,这确实是语言的设计方式。您如何建议该语言可以设计为使上述“安全”?

很多更多关于通用方差的信息,请参阅我在 NDC 2010 上关于该主题的演讲 - 转至 NDC video page 并搜索“方差”。

【讨论】:

  • 您的意思是string text = objects[0] 吗?
  • 我看到了问题,在这种情况下,这主要是个问题,因为我需要 IList 而不是 IEnumerable。不幸的是,在这种情况下,我无法使该类成为通用类。我想一个不错的解决方案可能是,当您尝试将更具体的 List 传递给需要较少实例的对象时,该实例会自动包装在 ReadOnlyCollection
  • @Chris:不,但我的意思是第二行中的objects = strings :)
  • @mko:你认为这就是语言应该为你做的事情吗?绝对不是,IMO。一定要创建自己的扩展方法以使其更简单,但变量的语言规则不应该与特定的集合类型混淆。
  • 也许隐含地这样做有点令人困惑,但也许可以通过某些语言功能显式地完成。如果我确实传递了一个只读的对象集合,那么能够以这种方式使用方差是非常自然的行为,你不觉得吗?
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 2012-09-27
  • 1970-01-01
相关资源
最近更新 更多