2010-01-14 119 views
39

我看到这个Array.ConvertAll方法,但它需要一个Converter作为参数。我不明白为什么我需要一个转换器,当我已经定义在我班上一个隐含的一个:C#Cast整个数组?

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

我想投的PointF秒的数组的Vec2秒的阵列。有没有一个很好的方法来做到这一点?或者我应该把它吮吸起来,写下(另一个)转换器或循环遍历元素?

+0

我通过这个问题和答案了解了一些很酷的东西!谢谢! – 2010-01-14 23:17:16

+3

@Terry:我问了很多微不足道的问题,因为我总是对答案感到惊讶:)解决问题很容易,但很难做到优雅。 – mpen 2010-01-15 00:24:42

+0

Duplicate:http://stackoverflow.com/questions/944174/best-way-to-cast-from-animal-to-dog – Mikhail 2010-01-15 16:18:38

回答

69

使用Cast /'Select'的建议LINQ解决方案很好,但由于您知道您在此处使用阵列,因此使用ConvertAll更加高效且简单。

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

使用ConvertAll指)的阵列仅遍历一次,不是两次,b)该操作是用于阵列(不使用IEnumerator<T>)更加优化。

不要让Converter<TInput, TOutput>类型混淆你 - 它只是一个简单的委托,因此你可以为它传递一个lambda表达式,如上所示。

+0

完美的作品!谢谢!我以为我必须定义''。 – mpen 2010-01-15 00:22:57

+3

没问题。是的,在C#2.0中,在你必须定义一个类型之前,幸运的是那些日子已经过去了。 – Noldorin 2010-01-15 00:39:11

15

强制转换不考虑用户定义的隐式转换,因此您不能像这样转换数组。您可以使用选择来代替:

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

或者写一个转换器:

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

,后者可能为结果的大小是预先知道的更有效。

+2

马克是正确的,我删除了我的答案。 – 2010-01-14 22:56:04

+0

感谢您将我的答案复制为您的编辑... – Noldorin 2010-01-14 23:29:55

+0

我在看到您的帖子之前已经写下了它。同样的确切的事情发生在我一个小时前在这里:http://stackoverflow.com/questions/2067778/sql-for-delete-query/。它有时会发生。不要把它当作个人 - 这只是一个巧合,即两个人看起来像是抄袭了另一个人,但两个人的答案完全相同。 – 2010-01-14 23:32:41

19

作为更新这个老问题,你现在可以做的:

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

myarray的地方包含源对象,VEC 2是你想投的类型。

+0

非常优雅,谢谢。 – Nyerguds 2013-12-17 11:55:28

+1

命名空间要求:使用System.Linq – 2016-08-01 08:18:50