1

I have a type Bar that defines an implicit cast operator:

public static implicit operator Bar(Foo foo)
{
    return new Bar(foo.property);
}

Converting single objects works great, but now I have a List<Foo> and I need a List<Bar>.

I found this workaround:

List<Bar> barList = fooList.ConvertAll<Bar>(item => item);

which seems to do the trick, but it's somewhat defeating the point of an implicit cast operator if I have to apply it in this somewhat explicit sense. Is there any way to make the implicit conversion work for lists?

null
  • 5,207
  • 1
  • 19
  • 35
  • 2
    http://stackoverflow.com/questions/4038125/covariance-in-c-sharp – spender Feb 09 '16 at 17:15
  • 1
    You haven't shown the code where you're consuming the list, that can potentially change the approach to take. For example. if you consume it via a foreach then you don't need to convert the list: https://dotnetfiddle.net/p3b8Bb –  Feb 09 '16 at 17:15
  • @AndyJ I pass these lists around as a whole. – null Feb 09 '16 at 17:23

1 Answers1

0

Unfortunately, you cannot make this cast implicit, although the reason is somewhat unexpected: when you explicitly provide a type argument to a generic method, C# requires you to provide all remaining arguments as well. It is this all-or-nothing approach that lets you write this

List<Bar> barList = fooList.Select(item => (Bar)item).ToList();

or this

List<Bar> barList = fooList.Select<Foo,Bar>(item => item);

but it does not let you write this:

List<Bar> barList = fooList.Select<...,Bar>(item => item);
//                                 ^^^
//                                  |
// Figure this out from the context |

Theoretically, C# could capture Foo from the type of item, but it does not have a feature to do it.

LINQ's Cast<T> is not going to work either, because it treats items being cast as plain objects, thus ignoring any conversion operators that may be defined on them.

Since you are required to specify both the "from" and the "to" types, a solution based on generics is not going to be any better than your solution based on ConvertAll.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Does `fooList.OfType().ToList()` not work here or does it suffer from the same issue around how the casting happens? – RobV Feb 09 '16 at 17:40
  • 1
    @RobV `OfType` would return an empty `IEnumerable`: it applies the same logic as `Cast`, but skips elements instead of throwing an exception when the cast is not possible. – Sergey Kalinichenko Feb 09 '16 at 17:42