86

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?

2
  • 5
    @Terry: I ask a lot of trivial questions because I'm always surprised by the answers :) It's easy to solve a problem, but hard to do it elegantly. Commented Jan 15, 2010 at 0:24
  • Duplicate: stackoverflow.com/questions/944174/… Commented Jan 15, 2010 at 16:18

5 Answers 5

133

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Works perfectly! Thank you! I thought I had to define the <types>.
No problem. And yeah, in C# 2.0 and before you would have had to define a type - fortunately those days are gone.
um, actually, I believe none of the proposed solutions will make the array be iterated twice, since both Cast and Select are implemented using deferred execution: msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/…
47

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.

1 Comment

Namespace required: using System.Linq
25

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.

Comments

5

The most efficient way is:

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

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

1 Comment

This is fast but b will always be null. You can't cast from an A[] to a B[] because the A array may contain non-B instances (e.g. C : A); that is, not every A is necessarily also a B. Instead, if you did B[] b = new B[9]; A[] a = b as A[]; then that would succeed because you are casting from a more-derived array type to a less-derived array type. You could even use A[] a = (A[]) b; because as would never fail to upcast. Even better would be A[] a = b; because the compiler knows that every B is also an A, therefore every B[] is also an A[].
1
+50

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.