C# Cast Entire Array?

I see this Array.ConvertAll method, but it requires a Converter as an argument. I don't see why I need a converter, when I've already defined an implicit one in my class:

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

I'm trying to cast an array of PointFs to an array of Vec2s. Is there a nice way to do this? Or should I just suck it up and write (another) converter or loop over the elements?

82290 次浏览

Cast doesn't consider user defined implicit conversions so you can't cast the array like that. You can use select instead:

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

Or write a converter:

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

The latter is probably more efficient as the size of the result is known in advance.

The proposed LINQ solution using Cast/'Select' is fine, but since you know you are working with an array here, using ConvertAll is rather more efficienct, and just as simple.

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

Using ConvertAll means
a) the array is only iterated over once,
b) the operation is more optimised for arrays (does not use IEnumerator<T>).

Don't let the Converter<TInput, TOutput> type confuse you - it is just a simple delegate, and thus you can pass a lambda expression for it, as shown above.

As an update to this old question, you can now do:

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

where myArray contains the source objects, and Vec2 is the type you want to cast to.

The most efficient way is:

class A { };
class B : A { };


A[] a = new A[9];
B[] b = a as B[];

This is an answer related to a bounty question asked by @user366312 and not to the original question.

What would be the solution in the case of .NET Framework 2.0?

As far as I know, LINQ was introduced to the.NET framework with version 3.5 back in 2007. So this means it is not possible to use LINQ in .NET Framework 2.0.

Therefore I would use just a regular for-loop and cast each element in the array.

Something like this without testing it:

var newArray = new NewType[myArray.Length];


for (var i = 0; i < myArray.Length; i++)
{
newArray[i] = (NewType)myArray[i];
}

You can wrap it up in a method like:

public static NewType[] ConvertAll(Vec2[] myArray)
{
var newArray = new NewType[myArray.Length];


for (var i = 0; i < myArray.Length; i++)
{
newArray[i] = (NewType)myArray[i];
}


return newArray;
}

And use it

var newArray = ConvertAll(myArray);