C
C#16mo ago
BenMcLean

❔ Casting range to bytes?

byte[] bytes = Enumerable.Range(0, 256).Cast<byte>().ToArray();
byte[] bytes = Enumerable.Range(0, 256).Cast<byte>().ToArray();
The result: System.InvalidCastException : Unable to cast object of type 'System.Int32' to type 'System.Byte'. Why? This should work! Why doesn't this work!?
8 Replies
BenMcLean
BenMcLean16mo ago
I know that this is a valid cast, because this should be equivalent to that:
byte[] bytes = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray();
byte[] bytes = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray();
and yet using Select works just fine.
DaVinki
DaVinki16mo ago
It's so sad that this isn't a thing But it doesn't work because it doesn't do explicit casting like you do in your Select It uses the is keyword, guaranteeing no loss of data If it's not to an inherited type, it won't work For this instance, int is not byte But given any reference type, say Rectangle, that is object
BenMcLean
BenMcLean16mo ago
Oh, that makes sense. The Cast method only works if the type being cast from is the type being cast to Thanks
DaVinki
DaVinki16mo ago
Or if you had a stream of boxed objects of type object, if you know 100% they are all Rectangle, you can do .Cast<Rectangle>() But yeah it's a shame there is no casting method that allows casting numbers that isn't select
MODiX
MODiX16mo ago
daVinki#5278
REPL Result: Success
const int Lengths = 5;

Console.WriteLine("rectangle -> object cast");
Enumerable.Range(1, Lengths)
.Select(a => new Rectangle(a, a))
.Cast<object>()
.ToList()
.ForEach(Console.WriteLine);

Console.WriteLine("\nobject -> rectangle cast");
Enumerable.Range(1, Lengths)
.Select(a => (object)new Rectangle(a, a))
.Cast<Rectangle>()
.ToList()
.ForEach(Console.WriteLine);

record Rectangle(int L, int W);
const int Lengths = 5;

Console.WriteLine("rectangle -> object cast");
Enumerable.Range(1, Lengths)
.Select(a => new Rectangle(a, a))
.Cast<object>()
.ToList()
.ForEach(Console.WriteLine);

Console.WriteLine("\nobject -> rectangle cast");
Enumerable.Range(1, Lengths)
.Select(a => (object)new Rectangle(a, a))
.Cast<Rectangle>()
.ToList()
.ForEach(Console.WriteLine);

record Rectangle(int L, int W);
Console Output
rectangle -> object cast
Rectangle { L = 1, W = 1 }
Rectangle { L = 2, W = 2 }
Rectangle { L = 3, W = 3 }
Rectangle { L = 4, W = 4 }
Rectangle { L = 5, W = 5 }

object -> rectangle cast
Rectangle { L = 1, W = 1 }
Rectangle { L = 2, W = 2 }
Rectangle { L = 3, W = 3 }
Rectangle { L = 4, W = 4 }
Rectangle { L = 5, W = 5 }
rectangle -> object cast
Rectangle { L = 1, W = 1 }
Rectangle { L = 2, W = 2 }
Rectangle { L = 3, W = 3 }
Rectangle { L = 4, W = 4 }
Rectangle { L = 5, W = 5 }

object -> rectangle cast
Rectangle { L = 1, W = 1 }
Rectangle { L = 2, W = 2 }
Rectangle { L = 3, W = 3 }
Rectangle { L = 4, W = 4 }
Rectangle { L = 5, W = 5 }
Compile: 855.536ms | Execution: 168.607ms | React with ❌ to remove this embed.
Aaron
Aaron16mo ago
because it effectively does
foreach (object o in enumerable)
yield return (T)o;
foreach (object o in enumerable)
yield return (T)o;
that cast there is an unboxing conversion, which can't do this
MODiX
MODiX16mo ago
Windows10CE#8553
REPL Result: Failure
object o = (int)27;
byte b = (byte)o;
object o = (int)27;
byte b = (byte)o;
Exception: InvalidCastException
- Unable to cast object of type 'System.Int32' to type 'System.Byte'.
- Unable to cast object of type 'System.Int32' to type 'System.Byte'.
Compile: 477.088ms | Execution: 29.689ms | React with ❌ to remove this embed.
Accord
Accord16mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.