2016-12-02 4 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

Ну да - если вы создали 'Компонент []', это * не * a 'FooComponent []' или какой-либо 'T'. Почему бы просто не использовать 'OfType () .ToArray()'? Почему вы называете 'Cast ()'? –

+1

'Cast ()' не имеет смысла. Если вы хотите 'T', зачем снова его переводить в« Компонент »? –

+0

Resharper заставил меня сделать это @JonSkeet :) – mashinkata

ответ

2

Вы можете написать:

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

Чтобы сделать это в одной строке.

Листинг не работает, потому что вы производите два типа, которые не совпадают, и массив объектов и массив из T, и это неверно.

+1

Что вы ожидаете от 'Select'? –

+0

@JonSkeet redundant thanks :) – 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: Но у вас stlil получил действительный оператор-оператор '(T [])'. Это необязательно, поскольку возвращаемый тип 'ToArray()' уже будет 'T []'. –