0

Is there a simple way to downcast an array of integers into an array of bytes?
Essentially, I would like to do the following thing (which does not work as is):

int[] myIntArray = new int[20];
byte[] byteArray = (byte[])myInArray;

The reason for doing this is that in my application myIntArray is actually a byte[], but was declared as an int[]. Meaning that only the least significant byte in myIntArray is of interest.

stackMeUp
  • 522
  • 4
  • 16
  • 2
    You know that the int array contains values that will fit in a byte, but the compiler doesn't. You'll have to cast each array element to a byte. – CodeCaster Aug 19 '19 at 12:26
  • `myIntArray is actually a byte[], but was declared as an int[]` - How did you get that to happen? P/Invoke? If so, correct the P/Invoke signature. – Matthew Watson Aug 19 '19 at 12:28
  • I wish I could, but I have to use this crappy 3rd party dll. Interestingly, their Python equivalent does not have this problem. Yes, the array of int[] only contains values between 0 and 255, which is the output from a first method. A second method however requires this output, but as a byte[] instead of the int[], lol – stackMeUp Aug 19 '19 at 12:29
  • Can't you correct the P/Invoke signature in your C# code? But wait, if the `int` array contains values like 0x00000001, 0x00000002, 0x00000003 then it is NOT an array of bytes at all; it really is an array of ints. – Matthew Watson Aug 19 '19 at 12:32
  • How would you do that on a third party dll? – stackMeUp Aug 19 '19 at 12:33
  • 1
    Assuming this 3rd party DLL is unmanaged, you must somewhere have a P/Invoke `DllImport` declaration. What does that look like? However, I'm thinking that what you have really is an array of `int` values (occupying 4 bytes each, but with only the lsb being non-zero), so you really can't cast it or fix it by changing the DLLImport declaration. – Matthew Watson Aug 19 '19 at 12:35
  • I'm just referring to it and including it via "using" as I would do "using System;". I then have access to its API. – stackMeUp Aug 19 '19 at 12:36
  • Ah so it isn't unmanaged - and it really is an array of ints. – Matthew Watson Aug 19 '19 at 12:37
  • @MatthewWatson - Thanks, I will stick to Jamiec's answer :-) – stackMeUp Aug 19 '19 at 12:37
  • Yes, array of int[], that should have been declare as an array of byte[] – stackMeUp Aug 19 '19 at 12:38
  • No, you cannot directly cast such an array. All you can do is copy the data. If performance matters, you might want to look at the SIMD (System.Numerics.Vectors) "Narrow" operation. – Marc Gravell Aug 19 '19 at 12:38

2 Answers2

5

You might think this would work:

byte[] myByteArray = myIntArray.Cast<byte>().ToArray();

But it doesnt - see Why Enumerable.Cast raises an InvalidCastException?

You can use Select though to project to a new array.

byte[] myByteArray = myIntArray.Select(i => (byte)i).ToArray();

Live demo: https://rextester.com/KVR50332

Jamiec
  • 133,658
  • 13
  • 134
  • 193
3

Try using Linq Select

byte[] byteArray = myIntArray.Select(i=> (byte)i).ToArray();
Antoine V
  • 6,998
  • 2
  • 11
  • 34