2

I know it's not possible to cast derived lists (why not is nicely explained here), but what about ImmutableArrays as they cannot be changed casting should be valid, right?

I would expect this to work:

class Animal {}
class Dog : Animal {}

ImmutableArray<Dog> dogs = ImmutableArray.Create<Dog>(new Dog());
ImmutableArray<Animal> animals = (ImmutableArray<Animal>) dogs;
ImmutableArray<Dog> dogsBack = (ImmutableArray<Dog>) animals;

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
DomenPigeon
  • 618
  • 7
  • 12
  • 1
    Why would you want to? Can't you access `dogs` as if it contained `Animal` instances or add `Dog` instances to `animals` on creation? – ChrisBD Aug 16 '23 at 08:24
  • @ChrisBD I need this for a caching scenario, I made an example [here](https://gist.github.com/DomenPigeon/27e28a1a77e12aa5ad0d4d31a7932762) – DomenPigeon Aug 16 '23 at 08:53

1 Answers1

3

Yes this is possible:

ImmutableArray<Dog> dogs = ImmutableArray.Create<Dog>(new Dog());
ImmutableArray<Animal> animals = ImmutableArray<Animal>.CastUp(dogs);
ImmutableArray<Dog> dogsBack = animals.CastArray<Dog>();

Note that you could also use CastArray to cast from dogs to animals, but due to covariance, CastUp is a significantly faster than the CastArray method.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
DomenPigeon
  • 618
  • 7
  • 12
  • 1
    Why do you need `ImmutableArray`'s `CastUp`? `dogs.CastArray()` should be enough? – Peter Csala Aug 16 '23 at 08:09
  • 3
    @PeterCsala both operations simply cast the underlying array with zero copy; "enough" suggests a difference - if anything, `CastUp` is preferable since it exploits a *known* covariance operation, rather than an unknown blind cast with type-test; source, for the curious: https://github.com/tunnelvisionlabs/dotnet-collections/blob/master/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray%601.cs#L1048-L1064 – Marc Gravell Aug 16 '23 at 08:18