Прочитать на английском

Поделиться через


Структура System.Byte

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Byte — это неизменяемый тип значения, представляющий незначенные целые числа со значениями, которые варьируются от 0 (который представлен константой Byte.MinValue) до 255 (которая представлена константой Byte.MaxValue). .NET также включает в себя 8-разрядный целочисленный тип, SByte, который представляет значения, которые варьируются от -128 до 127.

Создание экземпляра значения типа Byte

Можно создать экземпляр значения Byte несколькими способами:

  • Можно объявить переменную Byte и назначить ей литеральное целочисленное значение, которое находится в диапазоне типа данных Byte. В следующем примере объявляется две переменные Byte и присваивают им значения таким образом.

    byte value1 = 64;
    byte value2 = 255;
    
  • Числовое значение, не являющееся байтом, можно назначить байту. Это сужающее преобразование, поэтому требуется оператор приведения в C# и F# или метод преобразования в Visual Basic, если параметр Option Strict включен. Если значение, отличное от байтов, является Single, Doubleили Decimal значением, которое включает дробный компонент, обработка его дробной части зависит от компилятора, выполняющего преобразование. В следующем примере для Byte переменных назначается несколько числовых значений.

    int int1 = 128;
    try
    {
        byte value1 = (byte)int1;
        Console.WriteLine(value1);
    }
    catch (OverflowException)
    {
        Console.WriteLine($"{int1} is out of range of a byte.");
    }
    
    double dbl2 = 3.997;
    try
    {
        byte value2 = (byte)dbl2;
        Console.WriteLine(value2);
    }
    catch (OverflowException)
    {
        Console.WriteLine($"{dbl2} is out of range of a byte.");
    }
    // The example displays the following output:
    //       128
    //       3
    
  • Можно вызвать метод класса Convert для преобразования любого поддерживаемого типа в значение Byte. Это возможно, так как Byte поддерживает интерфейс IConvertible. Следующий пример иллюстрирует преобразование массива значений Int32 в значения Byte.

    int[] numbers = { Int32.MinValue, -1, 0, 121, 340, Int32.MaxValue };
    byte result;
    foreach (int number in numbers)
    {
        try
        {
            result = Convert.ToByte(number);
            Console.WriteLine($"Converted the {number.GetType().Name} value {number} to the {result.GetType().Name} value {result}.");
        }
        catch (OverflowException)
        {
            Console.WriteLine($"The {number.GetType().Name} value {number} is outside the range of the Byte type.");
        }
    }
    // The example displays the following output:
    //       The Int32 value -2147483648 is outside the range of the Byte type.
    //       The Int32 value -1 is outside the range of the Byte type.
    //       Converted the Int32 value 0 to the Byte value 0.
    //       Converted the Int32 value 121 to the Byte value 121.
    //       The Int32 value 340 is outside the range of the Byte type.
    //       The Int32 value 2147483647 is outside the range of the Byte type.
    
  • Чтобы преобразовать строковое представление значения Byte в Byte, можно вызвать метод Parse или TryParse. Строка может содержать десятичные или шестнадцатеричные цифры. В следующем примере показана операция синтаксического анализа с помощью десятичной и шестнадцатеричной строки.

    string string1 = "244";
    try
    {
        byte byte1 = Byte.Parse(string1);
        Console.WriteLine(byte1);
    }
    catch (OverflowException)
    {
        Console.WriteLine($"'{string1}' is out of range of a byte.");
    }
    catch (FormatException)
    {
        Console.WriteLine($"'{string1}' is out of range of a byte.");
    }
    
    string string2 = "F9";
    try
    {
        byte byte2 = Byte.Parse(string2,
                                System.Globalization.NumberStyles.HexNumber);
        Console.WriteLine(byte2);
    }
    catch (OverflowException)
    {
        Console.WriteLine($"'{string2}' is out of range of a byte.");
    }
    catch (FormatException)
    {
        Console.WriteLine($"'{string2}' is out of range of a byte.");
    }
    // The example displays the following output:
    //       244
    //       249
    

Выполнение операций со значениями байтов

Тип Byte поддерживает стандартные математические операции, такие как добавление, вычитание, деление, умножение, вычитание, отрицание и унарное отрицание. Как и другие целочисленные типы, тип Byte также поддерживает побитовые AND, OR, XOR, операторы сдвига влево и вправо.

Стандартные числовые операторы можно использовать для сравнения двух значений Byte или вызова метода CompareTo или Equals.

Вы также можете вызвать члены класса Math для выполнения широких числовых операций, включая получение абсолютного значения числа, вычисление кворента и остатка из целого деления, определение максимального или минимального значения двух целых чисел, получение знака числа и округление числа.

Представление байта в виде строки

Тип Byte обеспечивает полную поддержку стандартных и пользовательских строк числовых форматов. (Дополнительные сведения см. в типах форматирования, строках стандартного числового форматаи настраиваемых строк числовых форматов.) Однако чаще всего значения байтов представляются как однозначные и трехзначные значения без дополнительного форматирования или как шестнадцатеричные значения двухзначных значений.

Чтобы отформатировать значение Byte как целочисленную строку без начальных нулей, можно вызвать метод без параметров ToString(). Используя описатель формата "D", можно также включить указанное число начальных нулей в строковое представление. Используя описатель формата X, можно представить Byte значение в виде шестнадцатеричной строки. В следующем примере элементы в массиве значений Byte форматируется тремя способами.

byte[] numbers = { 0, 16, 104, 213 };
foreach (byte number in numbers)
{
    // Display value using default formatting.
    Console.Write("{0,-3}  -->   ", number.ToString());
    // Display value with 3 digits and leading zeros.
    Console.Write(number.ToString("D3") + "   ");
    // Display value with hexadecimal.
    Console.Write(number.ToString("X2") + "   ");
    // Display value with four hexadecimal digits.
    Console.WriteLine(number.ToString("X4"));
}
// The example displays the following output:
//       0    -->   000   00   0000
//       16   -->   016   10   0010
//       104  -->   104   68   0068
//       213  -->   213   D5   00D5

Можно также отформатировать значение Byte как двоичное, восьмеричное, десятичное или шестнадцатеричное значение, вызвав метод ToString(Byte, Int32) и указав базу в качестве второго параметра метода. В следующем примере этот метод вызывается для отображения двоичных, восьмимерных и шестнадцатеричных представлений массива байтовых значений.

byte[] numbers = { 0, 16, 104, 213 };
Console.WriteLine("{0}   {1,8}   {2,5}   {3,5}",
                  "Value", "Binary", "Octal", "Hex");
foreach (byte number in numbers)
{
    Console.WriteLine("{0,5}   {1,8}   {2,5}   {3,5}",
                      number, Convert.ToString(number, 2),
                      Convert.ToString(number, 8),
                      Convert.ToString(number, 16));
}
// The example displays the following output:
//       Value     Binary   Octal     Hex
//           0          0       0       0
//          16      10000      20      10
//         104    1101000     150      68
//         213   11010101     325      d5

Работа с не десятичными значениями байтов

Помимо работы с отдельными байтами в качестве десятичных значений, может потребоваться выполнять побитовые операции со значениями байтов или работать с массивами байтов или с двоичными или шестнадцатеричными представлениями байтовых значений. Например, перегрузки метода BitConverter.GetBytes могут преобразовать каждый из примитивных типов данных в массив байтов, а метод BigInteger.ToByteArray преобразует значение BigInteger в массив байтов.

Byte значения представлены в 8 битах только по величине без знака. Это важно учитывать при выполнении побитовых операций с значениями Byte или при работе с отдельными битами. Для выполнения числовых, логических операций или сравнения для двух не десятичных значений оба значения должны использовать одно и то же представление.

При выполнении операции с двумя значениями Byte значения используют одно и то же представление, поэтому результат является точным. Это иллюстрируется в следующем примере, который маскирует бит наименьшего порядка значения Byte, чтобы убедиться, что оно четное.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string[] values = { Convert.ToString(12, 16),
                          Convert.ToString(123, 16),
                          Convert.ToString(245, 16) };

      byte mask = 0xFE;
      foreach (string value in values) {
         Byte byteValue = Byte.Parse(value, NumberStyles.AllowHexSpecifier);
         Console.WriteLine($"{byteValue} And {mask} = {byteValue & mask}");
      }
   }
}
// The example displays the following output:
//       12 And 254 = 12
//       123 And 254 = 122
//       245 And 254 = 244

С другой стороны, при работе с беззначными и подписанными битами побитовые операции усложняются тем, что значения SByte используют представление знака и величины для положительных значений, а также дополнительное представление двух для отрицательных значений. Чтобы выполнить значимую побитовую операцию, значения должны быть преобразованы в два эквивалентных представления, а сведения о бите знака должны быть сохранены. В следующем примере это применяется для маскирования битов 2 и 4 в массиве из 8-разрядных значений со знаком и беззнаковых значений.

using System;
using System.Collections.Generic;
using System.Globalization;

public struct ByteString
{
    public string Value;
    public int Sign;
}

public class Example1
{
    public static void Main()
    {
        ByteString[] values = CreateArray(-15, 123, 245);

        byte mask = 0x14;        // Mask all bits but 2 and 4.

        foreach (ByteString strValue in values)
        {
            byte byteValue = Byte.Parse(strValue.Value, NumberStyles.AllowHexSpecifier);
            Console.WriteLine($"{strValue.Sign * byteValue} ({Convert.ToString(byteValue, 2)}) And {mask} ({Convert.ToString(mask, 2)}) = {(strValue.Sign & Math.Sign(mask)) * (byteValue & mask)} ({Convert.ToString(byteValue & mask, 2)})");
        }
    }

    private static ByteString[] CreateArray(params int[] values)
    {
        List<ByteString> byteStrings = new List<ByteString>();

        foreach (object value in values)
        {
            ByteString temp = new ByteString();
            int sign = Math.Sign((int)value);
            temp.Sign = sign;

            // Change two's complement to magnitude-only representation.
            temp.Value = Convert.ToString(((int)value) * sign, 16);

            byteStrings.Add(temp);
        }
        return byteStrings.ToArray();
    }
}
// The example displays the following output:
//       -15 (1111) And 20 (10100) = 4 (100)
//       123 (1111011) And 20 (10100) = 16 (10000)
//       245 (11110101) And 20 (10100) = 20 (10100)