views:

113

answers:

4

I tried to use the List.ConvertAll method and failed. What I am trying to do is convert a List to byte[]

I copped out and went this route but I need to figure out the ConvertAll method...

List<Int32> integers...
        internal byte[] GetBytes()
        {
            List<byte> bytes = new List<byte>(integers.Count * sizeof(byte));
            foreach (Int32 integer in integers)
                bytes.AddRange(BitConverter.GetBytes(integer));

            return bytes.ToArray();
        }
+2  A: 

How about

var bytes = integers.Select(i => BitConverter.GetBytes(i)).ToArray();

totally untested BTW, but seems reasonable.

This should actually give you an Array of arrays of bytes...which may or may not be what you need. If you want to collapse it into a single array, you can use SelectMany

var bytes = integers.SelectMany(i => BitConverter.GetBytes(i)).ToArray();
ckramer
+9  A: 

Since you don't want a byte[][] where each integer maps to an array of four bytes, you cannot call ConvertAll. (ConvertAll cannot perform a one-to-many conversion)

Instead, you need to call the LINQ SelectMany method to flatten each byte array from GetBytes into a single byte[]:

integers.SelectMany(BitConverter.GetBytes).ToArray()
SLaks
OoOoO I like. As for ConvertAll returning a byte[][], that was the exact problem I was having and was totally stumped. Thanks!
dirtmike
for those who havent moved to Visual Studio 2010 the syntax is ints.SelectMany(i => BitConverter.GetBytes(i)).ToArray()
zonkflut
@zonkflut: Or `integers.SelectMany<int, byte>(BitConverter.GetBytes).ToArray()`
SLaks
+2  A: 

The ConvertAll method is flawed because it expects there to be a 1:1 mapping from the source to the destination. This is not true when converting integers to bytes. You are much better off going with a solution such as what @SLaks has suggested with the SelectMany extension method.

Harry Steinhilber
+1  A: 

To use the ConvertAll method you can do the following...

Assuming that you have a list of ints that are really byte values and you do not actually want the bytes required to make up an int, i.e. byte[][]

public static class Utility {

   public static byte IntToByte(int i) {
      if(i < 0)
        return (byte)0;
      else if(i > 255)
        return (byte)255;
      else
       return System.Convert.ToByte(i);
   }
}

... to convert ...

byte[] array = listOfInts.ConvertAll(
                    new Converter<byte, int>(Utility.IntToByte) ).ToArray();

or you could use an anonymous delegate...

byte[] array = listOfInts.ConvertAll( new Converter<byte, int>(
                      delegate(int i) { 
                          if(i < 0)
                             return (byte)0;
                          else if(i > 255)
                             return (byte)255;
                          else
                             return System.Convert.ToByte(i);
                       }) ).ToArray();
Adrian Regan
System.Convert.ToByte will throw an OverflowException if the value is greater than byte.MaxValue.
Harry Steinhilber
True, then validate the integer and cap it if it exceed 255 or is less than 0. I think that the question asks how to use ConvertAll...
Adrian Regan