7

c#中有没有办法做这样的事情:

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

Goo 在哪里返回一个object[],使用反射或其他什么?

4

2 回答 2

7

您可以使用 LINQ:

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

在您的示例中,如果两种类型完全匹配,您将投射object[]到which 也将起作用: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:

Foo<string>();
于 2012-09-24T06:15:05.023 回答
1

也许最简单和最可靠的方法是复制数组,逐项进行强制转换:

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

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

  • 如果结果是引用类型,则进行castclass(即保留引用类型检查)T
  • 做一个unboxifT结果是值类型

引用类型的数组是协变的,这意味着 aT[]可以表示为 a 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;
}

一个令人烦恼的问题是我们现在有不同的语义——在某些情况下它是同一个数组,在某些情况下它是被复制的。如果我们改变数组,这可能会出现问题。

于 2012-09-24T06:38:31.603 回答