c# - 将 IEnumerable 转换为实现 IEnumerable 的类型
问题描述
给定:
如果您有以下价值观:
Type type
IEnumerable enumerable
并且满足以下条件:
typeof(IEnumerable).IsAssignableFrom(type)
enumerable.All(element => element.GetType() == type.GetElementType())
一般问题:
type
是否可以通过反射创建一个包含所有元素的实例enumerable
?
背景:
中的大多数类型System.Collections
都有一个类似的构造函数Example(ICollection)
,而 iftype
有一个这样的构造函数,它做起来很简单直接Activator.CreateInstance(type, enumerable)
。但是对于像这样的类型Dictionary<TKey, TValue>
,它并不是那么简单。我想到的唯一解决方案是这样的:
var dictionary = (IDictionary) Activator.CreateInstance(type);
var elementType = enumerable.First().GetType();
var key = elementType.GetProperty("Key");
var value = elementType.GetProperty("Value");
foreach (var element in enumerable)
{
dictionary.Add(key.GetValue(element), value.GetValue(element));
}
我更愿意接受这种KeyValuePair<TKey, TValue>
实现包含属性的接口的解决方案Key
,Value
因此您可以说:
var keyValuePair = (IKeyValuePair) element;
dictionary.Add(keyValuePair.Key, keyValuePair.Value);
而不是依靠反射来获取上述属性值。
此解决方案仅适用于System.Collections
强烈遵守所述类型定义的类型或自定义类型。
具体问题:
有没有一种更优雅的方法可以转换enumerable
为类型type
,也可以解释边缘情况MyCollection : ICollection
,比如我们不知道类型定义的情况?
更新:
这是一个例子:
var original = new Dictionary<int, string>
{
//values
};
var type = original.GetType();
var enumerable = original.AsEnumerable();
var copy = (Dictionary<int, string>) DoSomeMagic(type, enumerable);
object DoSomeMagic(Type type, IEnumerable enumerable)
{
//Add magic here
}
解决方案
这是使用 good old 为数不多的几个原因之一ArrayList
。
System.Array ConvertUnknownIEnumerableToArray(IEnumerable ienumerable, Type type)
{
var list = new ArrayList();
foreach (var i in ienumerable) list.Add(i);
return list.ToArray(type);
}
上面创建了一个强类型数组(命名array
),其中包含任何可枚举的命名中的具体对象ienumerable
。当然,数组实现ICollection
.
此技术允许您避免反射确定要创建和调用哪个泛型 MethodInfo 来创建数组。该框架为您完成。
推荐阅读
- javascript - 尝试在 JavaScript 中递归查找属性
- python - Python 导师 + 谷歌 Colab
- sql - 具有数字的相关子查询等于 where 条件下的子查询
- css - 如何使用 Sass Lint 允许重复的 CSS 属性?
- javascript - 使用 socket.io-stream 节点包通过 socket io 将文件从服务器发送到客户端(浏览器)
- python-3.x - 如何将输出打印到python中的文本文件
- python - 将 numpy.fill 与 Numba 'nopython' 模式一起使用
- django - 在 Django / Postgres 中选择每个组的最新项目的高性能方法
- c# - C# 如何从 SQL 数据库中填充对象列表
- c++ - C++ 中正确的核裂变模拟