2

Let's assume we have two ref types: A and B, and A implements the implicit cast operator (to B):

class A
{
    private B b;
    public static implicit operator B(A a) { return a.b; }
}
class B
{
}

What's the best (concise and/or fast) way to convert an array of A to an array of B ?

Cristian Diaconescu
  • 34,633
  • 32
  • 143
  • 233

1 Answers1

3

One thing that works and is reasonably straight-forward is using Linq:

A[] a = new A[5];//initialize elements
B[] b = a.Select(anA => (B)anA).ToArray();

However using Linq's Cast<> method does NOT work: (see why)

B[] b2 = a.Cast<B>.ToArray();//throws InvalidCastException


Update: here's one that doesn't use Linq:
B[] b = Array.ConvertAll(a, elem => (B) elem);

This could work in pre-lambda .NET 2.0 using a more verbose approach:

B[] b = Array.ConvertAll(a, 
            new Converter<A, B>(delegate(A elem) { return (B) elem; }));

...and possibly using the shorter version:

B[] b = Array.ConvertAll(a, delegate(A elem) { return (B) elem; });
Community
  • 1
  • 1
Cristian Diaconescu
  • 34,633
  • 32
  • 143
  • 233
  • 1
    +1, and as an interesting aside, `.Cast` accepts an `IEnumerable` (as opposed to `IEnumerable`) which is why the cast fails; it only sees an Enumerable of `Object`s not `A`s. `.Select()` remains the best approach. – Brad Christie Jan 25 '13 at 14:02
  • @Brad Regarding .Cast<> So what? What it does under the covers is trying to cast an instance (of object, yes) to (in this case) B. I spawned [this question](http://stackoverflow.com/q/14523530/11545) to delve deeper into the subject. – Cristian Diaconescu Jan 25 '13 at 14:16
  • Was that a question to me, or a general comment? – Brad Christie Jan 25 '13 at 14:19
  • @Brad It was both, I guess. Regarding your initial comment, I'm missing the relevance of Cast having a "vanilla" `IEnumerable` parameter. (Isn't it the whole point of `Cast` to take something type-less (non-generic) and transform it to something with a specified type?) – Cristian Diaconescu Jan 25 '13 at 14:30
  • 1
    Yes, but the runtime doesn't take in to account your `operator` methods of the custom object when it performs the cast, only the `boxing/unboxing` conversion. (And in this instance `A` is being boxed as an `Object` because of how generic `IEnumerable` is to `IEnumerable`.) – Brad Christie Jan 25 '13 at 14:38
  • @Brad A lot clearer now - so +1 for taking the time to explain! – Cristian Diaconescu Jan 25 '13 at 14:42