2016-12-02 87 views
0

嗨,我有以下的擴展方法未能轉換爲普通陣列

public static T[] GetComponentsOfType<T>(this GameObject source) where T : MonoBehaviour 
    { 
     Component[] matchingComponents = source.GetComponents<Component>().Where(comp => comp is T).ToArray(); 
     T[] castedComponents = new T[matchingComponents.Length]; 
     for (int i = 0; i < matchingComponents.Length; i++) 
     { 
      castedComponents[i] = (T) matchingComponents[i]; 
     } 
     return castedComponents; 
    } 

其中一期工程完全沒問題,但是我試圖通過只是一個單一的線縮短

return (T[]) source.GetComponents<Component>().OfType<T>().Cast<Component>().ToArray(); 

而且很顯然,這條線失敗將Component[]轉換爲T[],但是當我分別投射每個元素時,它會起作用(第一個示例)。這是爲什麼 ?

+1

好的 - 如果你已經創建了一個Component [],那*不是'FooComponent []'或者任何'T'。爲什麼不使用'OfType ().ToArray()'?你爲什麼打電話給'Cast ()'? –

+1

'Cast ()'沒有意義。如果你想要'T',爲什麼要再次將它轉換爲'Component'? –

+0

Resharper讓我這麼做@JonSkeet :) – mashinkata

回答

2

你可以寫:

source.GetComponents<Component>().OfType<T>().ToArray(); 

要做到這一點的一條線。

轉換失敗,因爲您正在轉換兩種不匹配的類型,並且組件的數組與T的數組無效。

+1

你期望'Select'做什麼? –

+0

@JonSkeet多謝,謝謝:) – Rafal

2

只能使用OfType<>。在你的解決方案中,你回到Component,這不能轉換爲T [],所以這個問題。

OfType<>已投下它。這就像一個替代Where(item => item is T).Cast<T>()

return source.GetComponents<Component>().OfType<T>().ToArray(); 
+2

沒有必要在這一點演員陣容...... –

+0

確實'return source.GetComponents ().OfType ().ToArray();'完全夠了,任務感謝你的快速反應! – mashinkata

+0

@JeroenvanLangen:但是你已經得到了實際的演員操作符'(T [])'。這是不必要的,因爲'ToArray()'的返回類型已經是'T []'。 –