传递结果时使用Array.Copy的方法更短?

时间:2017-11-20 21:12:05

标签: c#

我复制了数组的一部分,然后经常将它传递给构造函数。

有更简洁(并且仍然高效)的方法吗?在任何地方粘贴这3行代码(使用不同的MessageClass)感觉不是很干,但我无法弄清楚如何重构它。

// Example set-up
byte[] packetBody = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

// Different Message class each time I do this
// AuthenticationMessage.Length is a const ushort
var messageData = new byte[AuthenticationMessage.Length];
Array.Copy(packetBody, 0, messageData, 0, AuthenticationMessage.Length);
var message = new AuthenticationMessage(messageData);

编辑 - 如果它有帮助,这里是基类:

using System; 

abstract public class GameMessage {      

    public enum MessageTypes : ushort {
        POSITION = 1,
        AUTHENTICATION = 2,                
        REQUEST = 3
    };        

    public const ushort HeaderLength = 2;                                     
    public ushort Length { get; }
    public MessageTypes Type { get; }
    public byte[] Data { get; }

    protected GameMessage(ushort length, MessageTypes type, byte[] data = null) {
        Length = length;
        Type = type;
        Data = new byte[length];                       

        // Initialize if we were passed raw data
        if (data != null) {       
            Array.Copy(data, 0, Data, 0, length);
        }     
    }     

    public byte[] Header () {
        return F8Tools.FixEndian (BitConverter.GetBytes ((ushort)Type));
    }

    public byte[] Body () {
        var body = new byte[BodyLength()];
        Array.Copy(Data, HeaderLength, body, 0, BodyLength());
        return body;
    }     

    public ushort BodyLength () {
        return (ushort)(Length - HeaderLength);
    }         
}

其中一个子课程:

using System;

public class AuthenticationMessage : GameMessage {

    // Required for base class initialization
    public const ushort Length_ = 39;
    private const MessageTypes type = MessageTypes.AUTHENTICATION;
    public AuthenticationMessage (byte[] data) : base (Length_, type, data) {}
    // End required for base class initialization

    public enum Indices {
        ACCOUNT_ID_INDEX = 2,
        ACCOUNT_ID_LENGTH = 4,
        STATUS_INDEX = 6,
        STATUS_LENGTH = 1,
        HASH_INDEX = 7,
        HASH_LENGTH = 32,
    };

    public enum AuthStatuses : byte {
        REQUEST = 1,
        SUCCESS = 2,
        FAILURE = 3
    }

    public AuthStatuses AuthStatus () {
        return (AuthStatuses) Data[(int)Indices.STATUS_INDEX];
    }

    public AuthenticationMessage (int accountId, byte[] tokenHash) : base (Length_, type) {
        // Header
        Array.Copy(Header(), 0, Data, 0, HeaderLength);
        // Account ID
        byte[] idBytes = F8Tools.FixEndian (BitConverter.GetBytes(accountId));
        Array.Copy(idBytes, 0, Data, (int)Indices.ACCOUNT_ID_INDEX, (int)Indices.ACCOUNT_ID_LENGTH);
        // AuthStatus
        Data[(int)Indices.STATUS_INDEX] = (byte)AuthStatuses.REQUEST;
        // Token Hash
        Array.Copy(tokenHash, 0, Data, (int)Indices.HASH_INDEX, (int)Indices.HASH_LENGTH); // Hash char Length_ is 32
    }
}

2 个答案:

答案 0 :(得分:0)

你可以在MessageClass上编写一个静态方法,它接受一个byte []参数并返回一个新的MessageClass:

public static MessageClass NewMessageClass(byte[] packetBody)
{
    var messageData = new byte[Length];
    Array.Copy(packetBody, 0, messageData, 0, Length);
    return new MessageClass(messageData);
}

这样,逻辑就在一个地方定义,你可以从任何有权访问MessageClass的地方调用它。

答案 1 :(得分:0)

我最后写这篇来解决我的问题:

public static byte[] ArrayCopy(byte[] source, int length, int start = 0) {
    var dest = new byte[length];                                          
    Array.Copy(source, start, dest, 0, length);                           
    return dest;                                                          
}