Добавление GetInt64 / SetInt64 в ASP. NET Базовый сеанс - PullRequest
0 голосов
/ 01 мая 2020

Мне нужно добавить GetInt64 и SetInt64 инструкции к интерфейсу ISession в ASP. NET Core, чтобы мы могли хранить некоторые значения long.

Существующий код для GetInt32 и SetInt32 доступен на Github в SessionExtensions.cs.

Я пытаюсь понять используемый шаблон:

    public static void SetInt32(this ISession session, string key, int value)
    {
        var bytes = new byte[]
        {
            (byte)(value >> 24),
            (byte)(0xFF & (value >> 16)),
            (byte)(0xFF & (value >> 8)),
            (byte)(0xFF & value)
        };
        session.Set(key, bytes);
    }

    public static int? GetInt32(this ISession session, string key)
    {
        var data = session.Get(key);
        if (data == null || data.Length < 4)
        {
            return null;
        }
        return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    }

Я ожидал увидеть BitConverter.GetBytes, но по какой-то причине набор выполняет множество сдвигов вправо для каждого октета, а чтение выполняет сдвиги влево для каждого октета. Я предполагаю, что это связано с поддержанием нейтральности порядка байтов, поскольку методы BitConverter возвращают разные значения в зависимости от используемой архитектуры ЦП.

Есть ли очевидная причина, по которой код пишется так?

Будет ли следующая реализация правильной для SetInt64 / GetInt64?

    public static void SetInt64(this ISession session, string key, long value)
    {
        var bytes = new byte[]
        {
            (byte)(value >> 56),
            (byte)(0xFF & (value >> 48)),
            (byte)(0xFF & (value >> 40)),
            (byte)(0xFF & (value >> 32)),
            (byte)(0xFF & (value >> 24)),
            (byte)(0xFF & (value >> 16)),
            (byte)(0xFF & (value >> 8)),
            (byte)(0xFF & value)
        };
        session.Set(key, bytes);
    }

    public static long? GetInt64(this ISession session, string key)
    {
        var data = session.Get(key);
        if (data == null || data.Length < 8)
        {
            return null;
        }
        return data[0] << 56 | data[1] << 48 | data[2] << 40 | data[3] << 32 | data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
    }

1 Ответ

0 голосов
/ 07 мая 2020

Вы почти правы. Единственная проблема заключается в том, что в GetInt64 вам необходимо привести byte к long перед его сдвигом.

public static void SetInt64(this ISession session, string key, long value)
{
    var bytes = new byte[]
    {
    (byte)(value >> 56),
    (byte)(0xFF & (value >> 48)),
    (byte)(0xFF & (value >> 40)),
    (byte)(0xFF & (value >> 32)),
    (byte)(0xFF & (value >> 24)),
    (byte)(0xFF & (value >> 16)),
    (byte)(0xFF & (value >> 8)),
    (byte)(0xFF & value)
    };
    session.Set(key, bytes);
}

public static long? GetInt64(this ISession session, string key)
{
    var data = session.Get(key);
    if (data == null || data.Length < 8)
    {
        return null;
    }

    return (long)data[0] << 56 | (long)data[1] << 48 | (long)data[2] << 40 | (long)data[3] << 32 | (long)data[4] << 24 | (long)data[5] << 16 | (long)data[6] << 8 | (long)data[7];
}

В конечном итоге этот код и BitConverter приводят к одинаковому результату. BitConverter использует Unsafe для выполнения этой операции, возможно, именно поэтому она не используется. https://source.dot.net/#System .Private.CoreLib / BitConverter.cs, 107

Почему смещение?

Допустим, вы хотите сохранить 472 (число 3 ди git) в одном ди git заполнителях. Это то что ты делаешь.

  1. Возьмите первый ди git справа и поместите его на первое место.
  2. Сдвиньте число one di git вправо и повторите первый шаг.

Итак, получается

472 ---> 2

047 ---> 7

004 ---> 4

Это именно то, что здесь происходит, за исключением заполнителя - byte, который содержит 8 битов, и поэтому смещение происходит по 8 битов за раз .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...