gpt4 book ai didi

c# - 创建编译时未知类型的 ImmutableList

转载 作者:太空宇宙 更新时间:2023-11-03 23:14:10 25 4
gpt4 key购买 nike

给定一个 Collection<T>谁的类型T仅在运行时(而不是在编译时)已知,我想生成一个 ImmutableList<T> .

我想创建的方法可能像这样:

var immutableList = CreateImmutableList(originalList, type);

其中 originalList 是 IEnumerable类型是 T生成的 ImmutableList<T> .

怎么办?!

(我正在使用 NET .Core)

编辑:感谢评论,我找到了一个可行的解决方案。它使用 AddRange 方法。

namespace Sample.Tests
{
using System;
using System.Collections;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using Xunit;

public class ImmutabilityTests
{
[Fact]
public void CollectionCanBeConvertedToImmutable()
{
var original = new Collection<object>() { 1, 2, 3, 4, };
var result = original.AsImmutable(typeof(int));

Assert.NotEmpty(result);
Assert.IsAssignableFrom<ImmutableList<int>>(result);
}
}

public static class ReflectionExtensions
{
public static IEnumerable AsImmutable(this IEnumerable collection, Type elementType)
{
var immutableType = typeof(ImmutableList<>).MakeGenericType(elementType);
var addRangeMethod = immutableType.GetMethod("AddRange");
var typedCollection = ToTyped(collection, elementType);

var emptyImmutableList = immutableType.GetField("Empty").GetValue(null);
emptyImmutableList = addRangeMethod.Invoke(emptyImmutableList, new[] { typedCollection });
return (IEnumerable)emptyImmutableList;
}

private static object ToTyped(IEnumerable original, Type type)
{
var method = typeof(Enumerable).GetMethod("Cast", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(type);
return method.Invoke(original, new object[] { original });
}
}
}

最佳答案

您可以使用反射来做到这一点:

  1. 创造权利Type ImmutableList<T> 的对象
  2. 用数据填充它
  3. 归还

这是一个LINQPad演示的程序。我假设“不可变列表”是指 System.Collections.Immutable.ImmutableList<T>通过 Nuget 可用:

void Main()
{
object il = CreateImmutableList(new[] { 1, 2, 3, 4, 5 }, typeof(int));
il.GetType().Dump();
il.Dump();
}

public static object CreateImmutableList(IEnumerable collection, Type elementType)
{
// TODO: guard clauses for parameters == null
var resultType = typeof(ImmutableList<>).MakeGenericType(elementType);
var result = resultType.GetField("Empty").GetValue(null);
var add = resultType.GetMethod("Add");
foreach (var element in collection)
result = add.Invoke(result, new object[] { element });
return result;
}

输出:

System.Collections.Immutable.ImmutableList`1[System.Int32]

1
2
3
4
5

关于c# - 创建编译时未知类型的 ImmutableList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37857463/

25 4 0