5

I want to do this:

List<ushort> uList = new List<ushort>() { 1, 2, 3 };
List<short> sList = uList.Cast<short>().ToList();

but I get InvalidCastException "Specified cast is not valid."

How can I cast fast and efficient the above collection?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Tomislav Markovski
  • 12,331
  • 7
  • 50
  • 72
  • 1
    possible duplicate of [Puzzling Enumerable.Cast InvalidCastException](http://stackoverflow.com/questions/445471/puzzling-enumerable-cast-invalidcastexception) – Ani Feb 03 '11 at 16:21
  • 1
    @Ani: I would not consider that a duplicate because I know that you can't cast `int` to `long` (they're different sizes), but I would expect a cast from `ushort` to `short` to be possible because they're the same size. In other words, `(ushort[])(object)new short[] { 0, -1 }` is perfectly valid C#. – Gabe Feb 03 '11 at 16:43
  • @Gabe: It is the same issue. `(short)((ushort)1)` is valid C# as is `(long)((int)1)` (redundant cast for clarity). The issue is to do with mixing numeric-conversions and unboxing. http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx – Ani Feb 03 '11 at 16:51
  • I am going to point out the obvious problem of a value contained in the unsigned list being greater then the greatest value allowed by a signed short. – Security Hound Feb 03 '11 at 17:05
  • @Ani: `(long)((int)1)` is a conversion, while `(short)((ushort)1)` is a cast. They're the same syntax in C#, but the first performs a function call while the second doesn't (or doesn't have to). – Gabe Feb 03 '11 at 17:26
  • @Gabe: The issue the OP is facing is similar to why `(short)(object)(ushort)1` will throw at run-time. – Ani Feb 03 '11 at 17:33

2 Answers2

9

You could use ConvertAll:

List<short> sList = uList.ConvertAll(x => (short)x);
Eric Petroelje
  • 59,820
  • 9
  • 127
  • 177
7
List<short> sList = uList.Select(i => (short)i).ToList();
Rover
  • 2,203
  • 3
  • 24
  • 44