C# Cast Entire Array?

C#ArraysCasting

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

The most efficient way is:

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

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

Solution 5 - C#

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);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmpenView Question on Stackoverflow
Solution 1 - C#NoldorinView Answer on Stackoverflow
Solution 2 - C#RaviView Answer on Stackoverflow
Solution 3 - C#Mark ByersView Answer on Stackoverflow
Solution 4 - C#fdafadfView Answer on Stackoverflow
Solution 5 - C#Maytham FahmiView Answer on Stackoverflow