none
How to get <T> type length of bytes ? RRS feed

  • Question

  • I write the code to iterate the class properties.

    static class PacketCoder
    {
        public static byte[] PacketToData<T>(AppSignal signal, T packet)
        {
            byte[] dataBuf = new byte[1000];
            byte[] dataTemp = BitConverter.GetBytes((short)signal);
            Array.Copy(dataTemp, dataBuf, dataTemp.Length);
            int dataIndex = dataTemp.Length;
    
            Type t = packet.GetType();
            var props = t.GetProperties();
            foreach (var prop in props)
            {
                string name = prop.Name;
                object value = prop.GetValue(packet);
    
                if (value.GetType() == typeof(bool))
                {
                    dataTemp = BitConverter.GetBytes((bool)value);
                }
                else if (value.GetType() == typeof(short))
                {
                    dataTemp = BitConverter.GetBytes((short)value);
                }
                else if (value.GetType() == typeof(int))
                {
                    dataTemp = BitConverter.GetBytes((int)value);
                }
    
                Array.Copy(dataTemp, 0, dataBuf, dataIndex, dataTemp.Length);
                dataIndex += dataTemp.Length;
    
                Console.WriteLine("Name:   {0}", name);
                Console.WriteLine("Length: {0}", dataTemp.Length);
                Console.WriteLine("Value:  {0}", value);
                Console.WriteLine("");
            }
    
            byte[] dataFinal = new byte[dataIndex];
            Array.Copy(dataBuf, dataFinal, dataIndex);
            return dataFinal;
        }
    }
    

    I want to make the three if  to one:

                        if (value.GetType() == typeof(bool))
                        {
                            dataTemp = BitConverter.GetBytes((bool)value);
                        }
                        else if (value.GetType() == typeof(short))
                        {
                            dataTemp = BitConverter.GetBytes((short)value);
                        }
                        else if (value.GetType() == typeof(int))
                        {
                            dataTemp = BitConverter.GetBytes((int)value);
                        }
    

    Some one can you tell me how to do this?



    Monday, May 13, 2019 7:14 AM

Answers

  • Hi lihuipeng49,

    I have modified your code, and my program has no build errors.

    Code:

     public static byte[] EncodeSignalAndPacket<T>(AppSignal signal, T packet)
            {
                byte[] dataBuf = new byte[1000];
                byte[] dataTemp = BitConverter.GetBytes((short)signal);
                Array.Copy(dataTemp, dataBuf, dataTemp.Length);
                int dataIndex = dataTemp.Length;
    
                Type t = packet.GetType();
                var props = t.GetProperties();
                foreach (var prop in props)
                {
                    string name = prop.Name;
                    object value = prop.GetValue(packet);
                    try
                    {
                        if (value.GetType() == typeof(string))
                        {
                            byte[] dataTemp2 = Encoding.UTF8.GetBytes((string)value);
                            dataTemp = new byte[dataTemp2.Length + 1];
                            Array.Copy(dataTemp2, dataTemp, dataTemp2.Length);
                            Debug.Assert(dataTemp[dataTemp.Length - 1] == 0);
                        }
                        else if (value.GetType() == typeof(DateTime))
                        {
                            var dt = (DateTime)value;
                            dataTemp = BitConverter.GetBytes(dt.Ticks);
                            Debug.Assert(dataTemp.Length == 8);
                        }
                        else
                        {
                            dataTemp = BitConverter.GetBytes((dynamic)value);
                        }
                    }
                    catch
                    {
                        Debug.Assert(false, "PacketCoder无法解析的数据类型");
                    }
    
                    Array.Copy(dataTemp, 0, dataBuf, dataIndex, dataTemp.Length);
                    dataIndex += dataTemp.Length;
                }
    
                byte[] dataFinal = new byte[dataIndex];
                Array.Copy(dataBuf, dataFinal, dataIndex);
                return dataFinal;
            }

    I used the following code to test it, it works well.

    PAK_CS_CHAT_MESSAGE pak = new PAK_CS_CHAT_MESSAGE() { IsSystemMessage = true, Message = "ok", Nickname = "success" };
    PAK_SC_CHAT_MESSAGE pak2 = new PAK_SC_CHAT_MESSAGE() { Ip = "172", IsSystemMessage = true, Message = "test", Nickname = "hello", Number=12, Time=DateTime.Now };
    byte[] test1 = EncodeSignalAndPacket<PAK_SC_CHAT_MESSAGE>(AppSignal.SC_CHAT_MESSAGE, pak2);
    byte[] test2 = EncodeSignalAndPacket<PAK_CS_CHAT_MESSAGE>(AppSignal.CS_CHAT_MESSAGE, pak);

    Result:

    Best Regards,

    Jack



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, May 20, 2019 8:15 AM
    Moderator

All replies

  • Try this:

     

       dataTemp = BitConverter.GetBytes( (dynamic)value );

    Monday, May 13, 2019 7:50 AM
  • Hi

    Is your problem solved? If so, please post "Mark as answer" to the appropriate answer, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 15, 2019 8:39 AM
    Moderator
  • Sorry!

    There is no mail notify for me.

    I see the reply today.

    I use the suggestion, but there is an build error.

    error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

    I use the suggestion like this:

        public static byte[] EncodeSignalAndPacket<T>(AppSignal signal, T packet)
        {
            byte[] dataBuf = new byte[1000];
            byte[] dataTemp = BitConverter.GetBytes((short)signal);
            Array.Copy(dataTemp, dataBuf, dataTemp.Length);
            int dataIndex = dataTemp.Length;
    
            Type t = packet.GetType();
            var props = t.GetProperties();
            foreach (var prop in props)
            {
                string name = prop.Name;
                object value = prop.GetValue(packet);
    
                dataTemp = BitConverter.GetBytes((dynamic)value);
    
                if (value.GetType() == typeof(bool))
                {
                    dataTemp = BitConverter.GetBytes((bool)value);
                }
                else if (value.GetType() == typeof(short))
                {
                    dataTemp = BitConverter.GetBytes((short)value);
                }
                else if (value.GetType() == typeof(int))
                {
                    dataTemp = BitConverter.GetBytes((int)value);
                }
                else if (value.GetType() == typeof(long))
                {
                    dataTemp = BitConverter.GetBytes((long)value);
                }
                else if (value.GetType() == typeof(string))
                {
                    byte[] dataTemp2 = Encoding.UTF8.GetBytes((string)value);
                    dataTemp = new byte[dataTemp2.Length + 1];
                    Array.Copy(dataTemp2, dataTemp, dataTemp2.Length);
                    Debug.Assert(dataTemp[dataTemp.Length - 1] == 0);
                }
                else if (value.GetType() == typeof(DateTime))
                {
                    var dt = (DateTime)value;
                    dataTemp = BitConverter.GetBytes(dt.Ticks);
                    Debug.Assert(dataTemp.Length == 8);
                }
                else
                {
                    Debug.Assert(false, "PacketCoder无法解析的数据类型");
                }
    
                Array.Copy(dataTemp, 0, dataBuf, dataIndex, dataTemp.Length);
                dataIndex += dataTemp.Length;
            }
    
            byte[] dataFinal = new byte[dataIndex];
            Array.Copy(dataBuf, dataFinal, dataIndex);
            return dataFinal;
        }
    

    Thursday, May 16, 2019 10:36 AM
  • Hi lihuipeng49,

    Thanks for the feedback.

    For your question, could provide the related code about AppSignal?

    Besides, I want to know which line occurs the exception.

    We are waiting for your update.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, May 17, 2019 7:13 AM
    Moderator
  • enum AppSignal
    {
        SC_APP_WELCOME = 1,
        CS_APP_QUIT,
        CS_CONNECTION_HEARTBEAT,
    
        CS_CREATE_CHANNEL,
        CS_JOIN_CHANNEL,
        SC_CHANNEL_INFO,
        SC_MESSAGE_CLEAR,
    
        CS_CHAT_MESSAGE,
        SC_CHAT_MESSAGE,
    }
    
    class PAK_SC_APP_WELCOME
    {
        public short VersionCode { get; set; }
    }
    
    class PAK_CS_CONNECTION_HEARTBEAT
    {
    	public long PingCount { get; set; }
    }
    
    class PAK_CS_CHAT_MESSAGE
    {
        public string Nickname { get; set; }
        public string Message { get; set; }
        public bool IsSystemMessage { get; set; }
    }
    
    class PAK_SC_CHAT_MESSAGE
    {
        public short Number { get; set; }
        public string Nickname { get; set; }
        public string Message { get; set; }
        public bool IsSystemMessage { get; set; }
        public string Ip { get; set; }
        public DateTime Time { get; set; }
    }
    
    class PAK_SC_CHANNEL_INFO
    {
    	public int ChannelNumber { get; set; }
        public short ChaterCount { get; set; }
    }
    
    class PAK_SC_MESSAGE_CLEAR
    {
    
    }
    
    class PAK_CS_JOIN_CHANNEL
    {
    	public int ChannelNumber { get; set; }
        public short MessageNumberLast { get; set; }
        public string Nickname { get; set; }
    }
    
    class PAK_CS_CREATE_CHANNEL
    {
    }
    
    
    The 'T packet' pass the param will be one of the 'PAK_' class.
    Friday, May 17, 2019 11:33 PM
  • Hi lihuipeng49,

    I have modified your code, and my program has no build errors.

    Code:

     public static byte[] EncodeSignalAndPacket<T>(AppSignal signal, T packet)
            {
                byte[] dataBuf = new byte[1000];
                byte[] dataTemp = BitConverter.GetBytes((short)signal);
                Array.Copy(dataTemp, dataBuf, dataTemp.Length);
                int dataIndex = dataTemp.Length;
    
                Type t = packet.GetType();
                var props = t.GetProperties();
                foreach (var prop in props)
                {
                    string name = prop.Name;
                    object value = prop.GetValue(packet);
                    try
                    {
                        if (value.GetType() == typeof(string))
                        {
                            byte[] dataTemp2 = Encoding.UTF8.GetBytes((string)value);
                            dataTemp = new byte[dataTemp2.Length + 1];
                            Array.Copy(dataTemp2, dataTemp, dataTemp2.Length);
                            Debug.Assert(dataTemp[dataTemp.Length - 1] == 0);
                        }
                        else if (value.GetType() == typeof(DateTime))
                        {
                            var dt = (DateTime)value;
                            dataTemp = BitConverter.GetBytes(dt.Ticks);
                            Debug.Assert(dataTemp.Length == 8);
                        }
                        else
                        {
                            dataTemp = BitConverter.GetBytes((dynamic)value);
                        }
                    }
                    catch
                    {
                        Debug.Assert(false, "PacketCoder无法解析的数据类型");
                    }
    
                    Array.Copy(dataTemp, 0, dataBuf, dataIndex, dataTemp.Length);
                    dataIndex += dataTemp.Length;
                }
    
                byte[] dataFinal = new byte[dataIndex];
                Array.Copy(dataBuf, dataFinal, dataIndex);
                return dataFinal;
            }

    I used the following code to test it, it works well.

    PAK_CS_CHAT_MESSAGE pak = new PAK_CS_CHAT_MESSAGE() { IsSystemMessage = true, Message = "ok", Nickname = "success" };
    PAK_SC_CHAT_MESSAGE pak2 = new PAK_SC_CHAT_MESSAGE() { Ip = "172", IsSystemMessage = true, Message = "test", Nickname = "hello", Number=12, Time=DateTime.Now };
    byte[] test1 = EncodeSignalAndPacket<PAK_SC_CHAT_MESSAGE>(AppSignal.SC_CHAT_MESSAGE, pak2);
    byte[] test2 = EncodeSignalAndPacket<PAK_CS_CHAT_MESSAGE>(AppSignal.CS_CHAT_MESSAGE, pak);

    Result:

    Best Regards,

    Jack



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, May 20, 2019 8:15 AM
    Moderator
  • I use your code, but it not works.

    I think maybe there is using error.

    This is my using:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    
    And my devenv is VS2019, my project template is Xamarin.Forms

    Tuesday, May 28, 2019 1:25 AM
  • Hi lihuipeng49,

    Thanks for the feedback.

    I am using Console applications,it works well.

    You could change your current project to console application.

    If you still want to use your current project and the error still exists, you could ask it in the forums that is related to Xamarin.Forms.

    Because the Visual C# forum discusses and asks questions about the C# programming language, IDE, libraries, samples, and tools.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, May 28, 2019 7:56 AM
    Moderator
  • I found the reason!

    It works in .NET Standard 2.1

    It error in .NET Standard 2.0

    Thursday, May 30, 2019 10:31 PM