Re: Getting a byte array from a generic class

Steve Johnson <[email protected]> Tue, 18 May 2010 12:51:04 -0400
Newsgroups gmane.comp.windows.devel.dotnet.advanced
Message-ID <[email protected]>
OK, then do it this way:

public IntPtr AsByteArray(out int length)
{
    length = Marshal.SizeOf(typeof(T));

    IntPtr pb = Marshal.AllocHGlobal(length);

    Marshal.StructureToPtr(_value, pb, false);

    return pb;
}

--
Steve Johnson

On Tue, May 18, 2010 at 12:31 PM, Eddie Lascu <[email protected]> wrote:

> The problem is not bandwidth, as I would not have to serialize a ton of
> objects, but the actual size. These objects are wrapped in SNMP packets and
> sent down to field devices (dynamic message signs, speed detectors, traffic
> controllers, etc.). A field device will expect an integer to arrive encoded
> in 4 bytes, not 8. Binary serialization doesn't work for the exact same
> reason - the overhead bytes will be interpreted by something else and will
> confuse the field device.
>
> Thanks anyway for your suggestions.
>
> Regards,
> Eddie
>
>
> -----Original Message-----
> From: Discussion of advanced .NET topics. [mailto:
> [email protected]] On Behalf Of Steve Johnson
> Sent: Tuesday, May 18, 2010 12:24 PM
> To: [email protected]
> Subject: Re: [ADVANCED-DOTNET] Getting a byte array from a generic class
>
> Some other ideas, but they have issues:
>
> 1 - You could use binary serialization, but that would have a bunch of
> overhead.
>
> 2 - Since you will only be supporting numeric primitives, you could do the
> following, but it would be slow and require boxing.
>
> public byte[] AsByteArray()
> {
>    double d = (double)Convert.ChangeType(_value, typeof(double));
>    return BitConverter.GetBytes(d);
> }
>
> public void FromByteArray(byte[] bytes)
> {
>    double d = BitConverter.ToDouble(bytes, 0);
>    _value = (T)Convert.ChangeType(d, typeof(T));
> }
>
> This would also require 8 bytes for any value, which would be bad if
> bandwidth is an issue.
>
> --
> Steve Johnson
>
>
> On Tue, May 18, 2010 at 10:54 AM, Eddie Lascu <[email protected]> wrote:
>
> > Hi there,
> >
> > I need to pick your brains with regard to a more elegant solution to a
> > problem I'm dealing with right now. I have a generic class that wraps any
> > type of numeric values (short, int, decimal, double or float). Removing
> the
> > parts that are not interesting, this class is something like this:
> >
> >    public abstract class NumericNtcipObject<T> where T : struct,
> > IComparable<T>
> >    {
> >        protected NumericNtcipObject(T value)
> >        {
> >            double val;
> >            Debugging.Assert(typeof(T).IsValueType &&
> > typeof(T).IsPrimitive);
> >            Debugging.Assert(double.TryParse(value.ToString(), out val));
> >
> > Value = value;
> >        }
> >
> >        public T Value
> >        {
> >            set
> >            {
> >                _value = value;
> >            }
> >        }
> >
> >        public byte[] ValueAsByteStream
> >        {
> >            get
> >            {
> >                  // Need help here
> >            }
> >        }
> >
> >        protected T _value;
> >    }
> >
> > The class will be derived from and will only be instantiated with numeric
> > values. I want to create a property that can give me a byte array
> containing
> > all the bytes of the underlying value. If this would not be a generic
> class,
> > I could do:
> >
> > return BitConverter.GetBytes(Value);
> >
> > Unfortunately, BitConverter.GetBytes cannot resolve the type of Value so
> > this solution goes out the window. I need the exact number of bytes, so
> > casting to a type with a larger range is not good.
> >
> > I can do something like this:
> >
> >
> >        public byte[] ValueAsByteStream
> >        {
> >            get
> >            {
> >                if(typeof(T) == typeof(Int16))
> >                {
> >                    return BitConverter.GetBytes(Value.ToInt16(new
> > NumberFormatInfo()));
> >                }
> >
> >                if (typeof(T) == typeof(Int32))
> >                {
> >                    return BitConverter.GetBytes(Value.ToInt32(new
> > NumberFormatInfo()));
> >                }
> >
> >                if (typeof(T) == typeof(Int64))
> >                {
> >                    return BitConverter.GetBytes(Value.ToInt64(new
> > NumberFormatInfo()));
> >                }
> >
> >                if (typeof(T) == typeof(UInt16))
> >                {
> >                    return BitConverter.GetBytes(Value.ToUInt16(new
> > NumberFormatInfo()));
> >                }
> >
> >                if (typeof(T) == typeof(UInt32))
> >                {
> >                    return BitConverter.GetBytes(Value.ToUInt32(new
> > NumberFormatInfo()));
> >                }
> >
> >                if (typeof(T) == typeof(UInt64))
> >                {
> >                    return BitConverter.GetBytes(Value.ToUInt64(new
> > NumberFormatInfo()));
> >                }
> >                // rest of types here
> >
> >                return null;
> >            }
> >        }
> >
> > but this is not very nice.
> >
> > Can either of you smart guys give me a brilliant idea here?
> >
> > Thanks in advance,
> > Eddie
> >
> > ===================================
> > View archives and manage your subscription(s) at
> > http://peach.ease.lsoft.com/archives
> >
>
> ===================================
> View archives and manage your subscription(s) at
> http://peach.ease.lsoft.com/archives
>
> ===================================
> View archives and manage your subscription(s) at
> http://peach.ease.lsoft.com/archives
>

===================================
View archives and manage your subscription(s) at http://peach.ease.lsoft.com/archives