【问题标题】:Generic collection mapping using reflection使用反射的通用集合映射
【发布时间】:2013-01-28 10:15:58
【问题描述】:

如果任何类在其层次结构的某个阶段实现IEnumerable 接口,是否可以创建一个集合并填充该类?

我想编写一个简单的函数,如果它需要一个实现IList<>ICollection<>IEnumerable<> 等或者是Array 的对象(所以所有在某个阶段都实现IEnumerable)我可以用一组值填充它。

所以这个函数不知道它是否会收到List<object>object[],但可以同时填充两者。

谢谢。

【问题讨论】:

  • 一般情况下您无法填充 IEnumerable。这就是 IListICollection 存在的原因。但是您可以检查 _IEnumerable 是否实现了 ICollectionIList,如果是,则填充它。
  • 你想写一个函数,接受任何 IEnumerable 来填充其他(已知)集合,还是你真的想用 IEnumerable 来填充自己的更多值?
  • 你不能。例如 IEnumerable 也可以是只读集合后面的接口......你不能填充那些......
  • @poke 后者,我想取一个空的 IEnumerable 并用更多值填充它。实际上,您将传递 IEnumerable 类型,然后我将使用这些值创建它的填充实例。

标签: c# generics ienumerable


【解决方案1】:

IEnumerable 接口仅指定一种方法,该方法为您提供枚举器以枚举对象的项。因此,没有关于该对象的其他能力是什么的信息。因此,您无法从外部判断项目数量是固定的,还是可变的,甚至是可变的。

提供这个的第一个接口是IList,除了随机访问之外,它还提供了添加对象的方法。仅仅因为你有一个 IList 并不意味着你有写权限,因为 IList 可以是只读的。还有IDictionary,它为类字典对象指定添加方法。所有其他标准集合通常不实现为您提供此功能的接口。

因此,您不能在不知道其实现或至少一个更具体的实现细节(IList 或 IDictionary)的情况下用值填充任意集合。

我不需要捕获所有功能,我只需要涵盖大多数情况的东西。因此,如果通过了 IEnumerable、ICollection 或 IList,那么我可以只返回一个列表。

如果你得到一个IList<T>ICollection<T>,你也有一个IEnumerable<T>(因为两者都实现了它),所以你只有一个案例。您可以只接受一个 IEnumerable 并基于它创建一个列表:

public IList<T> CreateList<T> (IEnumerable<T> enumerable)
{
    List<T> list = new List<T>(enumerable);

    // add custom items
    list.Add(GetCustomItem<T>());

    return list;
}

如果您愿意,您还可以通过从定义中删除所有 &lt;T&gt;s 来制作非通用版本。

【讨论】:

  • 我不需要捕获所有功能,我只需要涵盖大多数实例的东西。因此,如果通过了 IEnumerable、ICollection 或 IList,那么我可以只返回一个列表。我试图迎合的是自定义集合的潜力,但我想要强制执行的是在某个阶段实现 IEnumerable。我可以把它提升到 ICollection。
  • 如果你只是想返回一个列表,你可以在你的函数中创建一个,添加 IEnumerable 中的所有项目,然后添加你的项目并将其作为 IList 返回。
猜你喜欢
  • 1970-01-01
  • 2014-11-22
  • 2015-03-18
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 2012-04-12
相关资源
最近更新 更多