2010-01-14 3 views
39

Я вижу этот метод Array.ConvertAll, но в качестве аргумента требуется Converter. Я не понимаю, почему мне нужен конвертер, когда я уже определил неявное один в моем классе:C# Cast Весь массив?

public static implicit operator Vec2(PointF p) 
    { 
     return new Vec2(p.X, p.Y); 
    } 

Я пытаюсь бросить массив PointF с в массив Vec2 с. Есть ли хороший способ сделать это? Или я должен просто сосать его и написать (другой) конвертер или цикл над элементами?

+0

Я изучил некоторые интересные вещи через этот вопрос и его ответы! Благодаря! –

+3

@Terry: Я задаю много тривиальных вопросов, потому что я всегда удивляюсь ответам :) Легко решить проблему, но это сложно сделать элегантно. – mpen

+0

Duplicate: http://stackoverflow.com/questions/944174/best-way-to-cast-from-animal-to-dog – Mikhail

ответ

69

Предлагаемое решение LINQ с использованием Cast/«Выбрать» прекрасно, но поскольку вы знаете, что работаете с массивом здесь, использование ConvertAll является скорее более эффективным, и столь же простым.

var newArray = Array.ConvertAll(array, item => (NewType)item); 

Использование ConvertAll означает а) массив только итерации один раз, а не в два раза, б) операция более оптимизирована для массивов (не использует IEnumerator<T>).

Не путайте тип Converter<TInput, TOutput> - это просто простой делегат, и, таким образом, вы можете передать для него выражение лямбда, как показано выше.

+0

Работает отлично! Спасибо! Я думал, что мне нужно определить ''. – mpen

+3

Нет проблем. И да, в C# 2.0 и прежде, чем вам пришлось бы определить тип - к счастью, эти дни ушли. – Noldorin

15

В ролях не рассматриваются пользовательские неявные преобразования, поэтому вы не можете использовать такой массив. Вы можете использовать вместо выбора:

myArray.Select(p => (Vec2)p).ToArray(); 

Или написать конвертер:

Array.ConvertAll(points, (p => (Vec2)p)); 

Последнее, вероятно, более эффективным, поскольку размер результата известен заранее.

+2

Марк верен, я удалил свой ответ. –

+0

Спасибо, что скопировали мой ответ как ваше редактирование ... – Noldorin

+0

Я уже писал это, прежде чем увидел ваше сообщение. То же самое случилось со мной всего час назад здесь: http://stackoverflow.com/questions/2067778/sql-for-delete-query/. Иногда бывает. Не принимайте это лично - это просто совпадение, что два человека приходят с таким же ответом, хотя похоже, что один скопировал другой. –

19

В качестве обновления к этому старому вопросу, теперь вы можете сделать:

myArray.Cast<Vec2>().ToArray(); 

где туАггау содержит исходные объекты, а vec2 типа вы хотите, чтобы бросить в.

+0

Очень элегантный, спасибо. – Nyerguds

+1

Необходимое пространство пространства: using System.Linq –