有沒有在C#的方式做這樣的事情:在運行時創建一個通用的陣列
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
凡咕返回object[]
,使用反射或什麼?
有沒有在C#的方式做這樣的事情:在運行時創建一個通用的陣列
public void Foo<T>()
{
T[] arr = Goo() as T[];
}
凡咕返回object[]
,使用反射或什麼?
你可以使用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>();
也許最簡單,最可靠的方法是將陣列複製,做投項目按項目:
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;
}
一個煩惱這雖然是我們現在有不同的語義 - 在某些情況下,它是在相同的陣列,在某些情況下被複制。如果我們變異了這個數組,這可能會有問題。
嗯......簽名中有'void',但是你返回數組?它不應該有'T []'作爲返回類型嗎? – Noctis
@Nocitus yup;編碼在'電話:)上的危險:) –
我不認爲'object []'可能永遠不是'T []'。一個'對象'可能是。 –
@Damien_The_Unbeliever:[協變和逆變在C#,第二部分:陣列協方差(http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-部分的兩陣列covariance.aspx) – Ani
@Ani - I可以誤讀一點,但它似乎是說,'對象[] A =新T []'將是有效的('其中,T:class'),不另一種方式。 –