-1

Is there a better way to convert a ListArray into a byte array in C#? The ListArray is coming from a dictionary object and contains a ListArray of objects where the underlying type is int. The only way I could get it to work was by looping thru the ListArray and individually inserting into the byte array. I was trying to get it to work with ToArray but I kept getting a cast error.

static void Main(string[] args) { int intLoop; byte[] arrByte; string strJson = "{\"Data\":[104,101,108,108,111,32,119,111,114,108,100]}"; Dictionary<string, object> dic = new Dictionary<string, object>(); JavaScriptSerializer js = new JavaScriptSerializer(); //deserialize json into dictionary object dic = js.Deserialize<Dictionary<string, object>>(strJson); //convert arraylist into byte array intLoop = 0; arrByte = new byte[((System.Collections.ArrayList)dic["Data"]).Count]; foreach (var s in (System.Collections.ArrayList)dic["Data"]) { arrByte[intLoop] = Convert.ToByte(s); intLoop++; } } 
2
  • JSON deserialization is built-in to the framework (at least if you're using .NET Core / .NET 5+), no need to use this legacy API. Also, the correct way to use it would be to create a model with a Data property of type List<byte>. learn.microsoft.com/en-us/dotnet/api/… Commented Jul 21, 2021 at 14:23
  • Any particular reason why you want to use ArrayList? It really shouldn;t be used anymore Commented Jul 21, 2021 at 22:02

3 Answers 3

2

There's nothing wrong with your approach, but, if you prefer, you could use a LINQ one-liner instead:

ArrayList data = ...; var arrByte = data.Cast<int>().Select(i => (byte)i).ToArray(); 

Note: Cast<int>() is required because your code uses the legacy ArrayList type. If your source type already implements IEnumerable<int> (for example, a List<int> or an int[]), you can skip this step.

Sign up to request clarification or add additional context in comments.

9 Comments

Sorry your answer gives only 11 bytes(the same is array length) , mine is 72. I guess because all number are less than 256. I don' t know which is true, trying to make some research
If you try this array var data= [104,101,108,108,111,32,119,111,114,308,300] you will see very strange result.
@Serge: I believe it's because you used BinaryFormatter, which dumps type information, field names and object ids into the stream. When using generic types the overhead can be really brutal.
This data is coming from a file that has been converted to a byte array so the data should always be less than 256.
@Heinzi Hey, I had a pet dinosaur. I'm going to upgrade right now. Thanks!
|
1

The problem is that int[] and byte[] are the same when all numbers are less 255. If one of the numbers is large than 255 it will throw exeption during conversion.

If you need byte[]

string strJson = "{\"Data\":[104,101,108,108,111,32,119,111,114,108,100]}"; var byteArray = JsonConvert.DeserializeObject<RootData>(strJson); 

class

public class RootData { public byte[] Data {get; set;} } 

5 Comments

+1 for using an object model instead of just serializing to a dictionary. I wonder if this can be simplified by declaring Data directly as byte[] (and skipping all the conversion stuff)...
@Heinzi Thanks, I added your answer to mine, if you don't mind
In my case I'm probably stuck using the dictionary<string,object>. I simplified my example but in reality there are many more data entries of different types in my actual dictionary object.
Are you sure you want to recommend using BinaryFormatter? It is planned to be removed from .NET due to its security flaws. Once I collected some of the mayor issues in this answer.
I know this, but the problem is what PO wants. You int[] and byte[] are the same when all numbers are less 255. If one of the numbers is large than 255 it should throw exeption.
0

That's how I would write it (using c# 9 language features)

public record MyDto(IEnumerable<int> Data); var json = "{\"Data\":[104,101,108,108,111,32,119,111,114,108,100]}"; var document = JsonSerializer.Deserialize<MyDto>(json); var bytes = document?.Data .Select(i => (byte) i) .ToArray(); 
  1. Create data structure to represent the input data
  2. Parse it with System.Text.Json JsonSerializer (the new standard json serializer)
  3. Convert it with LINQ

4 Comments

I'll have to check out that json serializer. I was just using the first one I found. :)
I thought "better way" may include "do not use legacy components" ;-)
int[] and byte[] are the same when all numbers are less 255. If one of the numbers is large than 255 it should throw exeption. So you don' t need any select, just change IEnumerable<byte>
IList<> would break immutability of the dto, so I'd use IEnumerable<byte> instead. But one could argue that the correct representation of the json is a collection of numbers and the requirement to convert this to bytes comes later. Or it's 1:1 and directly deserializing to the final type is the better approach. I think IEnumerable<byte> is the better solution here but I didn't test it that's why I don't update the answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.