mpen
mpen

Reputation: 282825

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?

Upvotes: 85

Views: 96518

Answers (5)

Maytham Fahmi
Maytham Fahmi

Reputation: 33387

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

Upvotes: 2

fdafadf
fdafadf

Reputation: 819

The most efficient way is:

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

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

Upvotes: 5

Noldorin
Noldorin

Reputation: 147240

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.

Upvotes: 131

Ravi
Ravi

Reputation: 459

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.

Upvotes: 45

Mark Byers
Mark Byers

Reputation: 838036

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.

Upvotes: 24

Related Questions