c#中有没有办法做这样的事情:
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
Goo返回object[]
,使用反射或其他什么?
答案 0 :(得分:5)
您可以使用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:
Foo<string>();
答案 1 :(得分:0)
也许最简单和最可靠的方法是复制数组,逐个项目进行:
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;
}
然而,一个令人烦恼的是我们现在有不同的语义 - 在某些情况下它是相同的数组,在某些情况下它被复制。如果我们 mutate 数组,这可能会有问题。