在运行时创建一个通用的阵列(Creating a generic array at runtime)

2019-09-22 21:35发布

有没有在C#的方式做这样的事情:

public void Foo<T>()
{
    T[] arr = Goo() as T[];
}

凡咕返回一个object[]使用反射或什么?

Answer 1:

你可以使用LINQ:

public void Foo<T>()
{
    T[] arr = Goo().OfType<T>().ToArray();
}

在你的榜样,你是铸造的object[]T[]如果这两种类型完全匹配这也将工作:

public void Foo<T>()
{
    T[] arr = Goo() as T[];
    if (arr != null)
    {
        // use the array
    }
}

例如,这将在以下情况下工作:

public object[] Goo()
{
    return new string[] { "a", "b" };
}

然后调用美孚这样的:

Foo<string>();


Answer 2:

也许最简单,最可靠的方法是将阵列复制,做投项目按项目:

public void Foo<T>()
{
    T[] arr = Array.ConvertAll(Goo(), x => (T)x);
}

这是一个“ unbox.any ”,这意味着(于JIT):

  • 做一个castclass (即参考保留型检查)如果T原来是引用类型
  • 做一个unbox如果T原来是数值类型

的引用类型的数组是协变的,这意味着一个T[]可被表示为一个object[] 正因为如此,有机会的结果Goo()实际上 T[] 我们可能还需要对此进行测试:

public T[] Foo<T>()
{
    var tmp = Goo();
    T[] arr = tmp as T[];
    if(arr == null && tmp != null) {
        arr = Array.ConvertAll(Goo(), x => (T)x);
    }
    return arr;
}

这虽然的一个烦恼的是,我们现在有不同的语义 - 在某些情况下,它是在相同的阵列,在某些情况下被复制。 如果我们发生变异的阵列,这可能是有问题的。



文章来源: Creating a generic array at runtime