• 0

Buffer.BlockCopy Passing Generic Argument


Question

Hi all,

I'm trying to pass a value constrained type to BitConverter.GetBytes, but c# only permits a struct constraint. For example:

        private void writePrimitive<T>(T obj) where T : struct {
            if (!typeof(T).IsPrimitive)
                throw new ArgumentException("Only primitive types allowed");
            
            Buffer.BlockCopy(BitConverter.GetBytes(obj), 0, buf, pos, sizeof(obj));
            update(sizeof(obj));
        }
The compiler understandably borks at this. Still I'd like to find a solution that avoids repetition and doesn't require writing multiple overloads for different primitives.
Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

A common technique to get around the limitations of generic constrains is to parameterize the non-generic functions you want to use. So:

        private void writePrimitive<T>(Func<T, byte[]> getBytes, T obj) {
            byte[] bytes = getBytes(obj);
            Buffer.BlockCopy(bytes, 0, buf, pos, bytes.Length);
            update(bytes.Length);
        }
       
        // Usage:
        writePrimitive(BitConverter.GetBytes, 3);
        writePrimitive(BitConverter.GetBytes, true);

Can't get around having to repeat BitConverter.GetBytes, but that's about as good as it gets I think. Type inference figures out what overload to call based on the type of the second parameter.

Link to comment
Share on other sites

  • 0

A common technique to get around the limitations of generic constrains is to parameterize the non-generic functions you want to use. So:

        private void writePrimitive<T>(Func<T, byte[]> getBytes, T obj) {
            byte[] bytes = getBytes(obj);
            Buffer.BlockCopy(bytes, 0, buf, pos, bytes.Length);
            update(bytes.Length);
        }
       
        // Usage:
        writePrimitive(BitConverter.GetBytes, 3);
        writePrimitive(BitConverter.GetBytes, true);

Can't get around having to repeat BitConverter.GetBytes, but that's about as good as it gets I think. Type inference figures out what overload to call based on the type of the second parameter.

Perfect. Thanks Andre.

A delegate also worked for the read back function. 

Link to comment
Share on other sites

This topic is now closed to further replies.