c# - 从另一个 IEnumerable 填充任意具体的 IEnumerable

标签 c# reflection ienumerable

我正在写一些反射代码。呃,好吧。


我有一个 IEnumerable<TData>值对象,和一个 Expression<Func<TInstance, IEnumerable<TData>>>表示其类型实现(但未声明)IEnumerable<TData> 的属性.

例如我有一个属性(property)声明为: public SomeProp List<String> {get;set;} , 一个值对象 new[] {"a", "bee", "sea"} ,以及表达式 obj => obj.SomeProp

我已经成功编写了提取信息的代码:

the concrete implementation of IEnumerable<> for SomeProp is List<>

因此我可以调用 values.ToList()在我的 IEnumerable<string> values 对象并成功将结果分配给属性。

对于 IEnumerable<> 的任何特定实现我可以手动编写代码来检测该实现,并编写代码来创建满足它的具体对象。 实际上,我目前有一个小型映射字典,其中涵盖了一些情况:

new Dictionary<Type, Func<IEnumerable<TProp>, IEnumerable<TProp>>>
{
    { typeof(List<>), (vals) => vals.ToList() },
    { typeof(IList<>), (vals) => vals.ToList() },
    { typeof(Collection<>), (vals) => new Collection<TProp>(vals.ToList()) },
    { typeof(ICollection<>), (vals) => new Collection<TProp>(vals.ToList()) },
};

当然,这甚至没有涵盖大多数常见情况,更不用说涵盖所有可能的情况了!


有什么方法可以编写采用任意“值”的反射代码 IEnumerable<T>和目标具体 IEnumerable<T> ,并根据值创建具体实例?

这似乎有点乐观,但我觉得值得一问 :)

最佳答案

TL;DR:在一般情况下,这是不可能的。最后,这只是接口(interface)不能直接构造的问题。

在 .NET 框架类型中

如果你的目标类型确实是像List<>这样的具体类型或 Collection<> , 那么就可以从它的 Type 中创建一个实例目的。您仍然必须假设存在一个接受 IEnumerable<T> 的构造函数作为第一个也是唯一的论点。即使使用常见的框架类型也不是这种情况:

Type[] types = { typeof(List<string>), typeof(IList<string>), typeof(Collection<string>), typeof(ICollection<string>) };
IEnumerable<T> values = new List<T> { /* ... */ };
foreach (var type in types) {
    var concreteInstance = type.GetConstructor(new Type[] { typeof(IEnumerable<T>) })?.Invoke(new object[] { values });
    // Succeeds for List<>.
    // Fails for IList<> as not a concrete type.
    // Fails for Collection<> as no constructor accepts IEnumerable as first argument.
    // Fails for ICollection as not a concrete type.
}

一般情况

让我们定义以下接口(interface):

interface IArbitrary<T> : IEnumerable<T> { }

事实上,目前还没有这个接口(interface)的具体实现。因此,无论您多么努力地尝试,反射代码都不可能从 IArbitrary<T> 中创建“目标具体 IEnumerable<T>”。

关于c# - 从另一个 IEnumerable 填充任意具体的 IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58834774/

相关文章:

c# - WPF 应用程序完全卡住 1 分钟

c# - DataContractJsonSerializer 生成 Ghost 字符串到 JSON 键?

java - 将逻辑注入(inject)到 spring 组件扫描过程中

java - 反射 - 在 Java 中动态地将对象转换为其父类(super class)

c# - 当 skip 不能被 take 整除时,通过 pageIndex/pageSize 分页实现 skip/take 分页

c# - 如何跳过 Json.Net 中 IEnumerable 类型的默认 JavaScript 数组序列化?

c# - IEnumerable<char> 到字符串

c# - 一次读取一个字符的文本文件时检测换行

c# - 文本字段字符串在 C# 中被删除

java - 从动态编译的源代码中实例化一个对象