c#中有没有办法做这样的事情:
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
Goo 在哪里返回一个object[]
,使用反射或其他什么?
c#中有没有办法做这样的事情:
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
Goo 在哪里返回一个object[]
,使用反射或其他什么?
您可以使用 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>();
也许最简单和最可靠的方法是复制数组,逐项进行强制转换:
public void Foo<T>()
{
T[] arr = Array.ConvertAll(Goo(), x => (T)x);
}
这是一个“ unbox.any
”,这意味着(对 JIT):
castclass
(即保留引用类型检查)T
unbox
ifT
结果是值类型引用类型的数组是协变的,这意味着 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;
}
一个令人烦恼的问题是我们现在有不同的语义——在某些情况下它是同一个数组,在某些情况下它是被复制的。如果我们改变数组,这可能会出现问题。