Is there a way in c# to do something like this:
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
Where Goo returns an object[], Using reflection or whatever?
You could use LINQ:
public void Foo<T>()
{
T[] arr = Goo().OfType<T>().ToArray();
}
In your example you are casting the object[] to T[] which will also work if the two types match exactly:
public void Foo<T>()
{
T[] arr = Goo() as T[];
if (arr != null)
{
// use the array
}
}
For example this will work in the following case:
public object[] Goo()
{
return new string[] { "a", "b" };
}
and then calling Foo like this:
Foo<string>();
Perhaps the simplest and most reliable approach is to copy the array, doing the cast item-by-item:
public void Foo<T>()
{
T[] arr = Array.ConvertAll(Goo(), x => (T)x);
}
This is an "unbox.any", which means (to the JIT):
castclass (i.e. reference-preserving type-check) if T turns out to be reference-typeunbox if T turns out to be value-typeArrays of reference-types are covariant, meaning that a T[] can be represented as an object[]. Because of this, there is a chance that the result of Goo() is actually a T[]. We might also want to test this:
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;
}
One annoyance of this though is that we now have different semantics - in some cases it is the same array, in some cases it is copied. This could be problematic if we mutate the array.
void in the signature, yet you return the array? Shouldn't it have a T[] as a return type?
object[]could ever be aT[]. Anobjectcould be though.object[] a = new T[]will be valid (where T:class), not the other way around.object[]actually is ;p SinceT[]can be represented as anobject[], it is possible that yourobject[]is actually aT[]. However, if the array is constructed as anobject[]but happens to contain allT, then indeed: the cast will fail.