Protobuf スカラー データ型Protobuf scalar data types

プロトコル バッファ (Protobuf) は、ネイティブスカラー値の種類の範囲をサポートします。Protocol Buffer (Protobuf) supports a range of native scalar value types. 次の表は、それらすべてを同等の C# 型と共に示しています。The following table lists them all with their equivalent C# type:

プロトブーフタイプProtobuf type C# 型C# type NotesNotes
double double
float float
int32 int 11
int64 long 11
uint32 uint
uint64 ulong
sint32 int 11
sint64 long 11
fixed32 uint 22
fixed64 ulong 22
sfixed32 int 22
sfixed64 long 22
bool bool
string string 33
bytes ByteString 44

注:Notes:

  1. 署名付int32int64の値を使用する場合は、標準エンコードは非効率的です。The standard encoding for int32 and int64 is inefficient when you're working with signed values. フィールドに負の数が含まれる可能性がある場合sint32sint64、またはを使用します。If your field is likely to contain negative numbers, use sint32 or sint64 instead. これらの型は、それぞれintC#longと型にマップされます。These types map to the C# int and long types, respectively.
  2. フィールドfixedは、値が何であるかに関係なく、常に同じバイト数を使用します。The fixed fields always use the same number of bytes no matter what the value is. この動作により、シリアル化と逆シリアル化が大きい値に対して高速になります。This behavior makes serialization and deserialization faster for larger values.
  3. プロトブフ文字列は UTF-8 (または 7 ビット ASCII) でエンコードされています。Protobuf strings are UTF-8 (or 7-bit ASCII) encoded. エンコードされた長さは 232より大きくすることはできません。The encoded length can't be greater than 232.
  4. Protobuf ランタイムは、C#ByteString``byte[]配列との間で簡単にマップする型を提供します。The Protobuf runtime provides a ByteString type that maps easily to and from C# byte[] arrays.

その他の .NET プリミティブ型Other .NET primitive types

日付と時刻Dates and times

ネイティブ スカラー型は、日付DateTimeOffsetと時刻の値DateTimeを提供しません。 TimeSpanThe native scalar types don't provide for date and time values, equivalent to C#'s DateTimeOffset, DateTime, and TimeSpan. Google の「よく知られているタイプ」の拡張機能を使用して、これらのタイプを指定できます。You can specify these types by using some of Google's "Well Known Types" extensions. これらの拡張機能は、サポートされているプラットフォーム全体で、複雑なフィールド型のコード生成とランタイムサポートを提供します。These extensions provide code generation and runtime support for complex field types across the supported platforms.

次の表は、日付と時刻の種類を示しています。The following table shows the date and time types:

C# 型C# type プロトブーフの有名なタイプProtobuf well-known type
DateTimeOffset google.protobuf.Timestamp
DateTime google.protobuf.Timestamp
TimeSpan google.protobuf.Duration
syntax = "proto3"

import "google/protobuf/duration.proto";  
import "google/protobuf/timestamp.proto";

message Meeting {

    string subject = 1;
    google.protobuf.Timestamp time = 2;
    google.protobuf.Duration duration = 3;

}  

C# クラスで生成されるプロパティは、.NET の日付と時刻の型ではありません。The generated properties in the C# class aren't the .NET date and time types. プロパティは、名前空間TimestampDurationの クラスGoogle.Protobuf.WellKnownTypesと クラスを使用します。The properties use the Timestamp and Duration classes in the Google.Protobuf.WellKnownTypes namespace. これらのクラスは、 DateTimeOffsetDateTime、および とのTimeSpan間で変換するためのメソッドを提供します。These classes provide methods for converting to and from DateTimeOffset, DateTime, and TimeSpan.

// Create Timestamp and Duration from .NET DateTimeOffset and TimeSpan
var meeting = new Meeting
{
    Time = Timestamp.FromDateTimeOffset(meetingTime), // also FromDateTime()
    Duration = Duration.FromTimeSpan(meetingLength)
};

// Convert Timestamp and Duration to .NET DateTimeOffset and TimeSpan
DateTimeOffset time = meeting.Time.ToDateTimeOffset();
TimeSpan? duration = meeting.Duration?.ToTimeSpan();

注意

このTimestamp型は UTC 時刻で動作します。The Timestamp type works with UTC times. DateTimeOffset値は常にゼロのオフセットをDateTime.Kind持ち、プロパティはDateTimeKind.Utc常に です。DateTimeOffset values always have an offset of zero, and the DateTime.Kind property is always DateTimeKind.Utc.

System.GuidSystem.Guid

Protobuf は、他のプラットフォームGuidと呼ばれるUUID型を直接サポートしていません。Protobuf doesn't directly support the Guid type, known as UUID on other platforms. よく知られているタイプはありません。There's no well-known type for it.

最適な方法は、標準Guid``string``8-4-4-4-12の 16 進形式 (たとえば)45a9fda3-bd01-47a9-8460-c1cd7484b0b3を使用して、値をフィールドとして処理することです。The best approach is to handle Guid values as a string field, by using the standard 8-4-4-4-12 hexadecimal format (for example, 45a9fda3-bd01-47a9-8460-c1cd7484b0b3). すべての言語とプラットフォームは、その形式を解析できます。All languages and platforms can parse that format.

Guid値にフィールドをbytes使用しないでください。Don't use a bytes field for Guid values. Protobuf が Java などの他のプラットフォームと対話しているとき、エンディアンネス(Wikipedia 定義) の問題は、不安定な動作を引き起こす可能性があります。Problems with endianness (Wikipedia definition) can result in erratic behavior when Protobuf is interacting with other platforms, such as Java.

Null 許容型Nullable types

C# の Protobuf コード生成では、intネイティブ型を使用int32します。The Protobuf code generation for C# uses the native types, such as int for int32. したがって、値は常に含まれ、null にすることはできません。So the values are always included and can't be null.

C# コードでの使用int?など、明示的な null を必要とする値の場合、Protobuf の "既知の型" には、null 許容 C# 型にコンパイルされるラッパーが含まれます。For values that require explicit null, such as using int? in your C# code, Protobuf's "Well Known Types" include wrappers that are compiled to nullable C# types. これらを使用するには、次wrappers.protoのように.protoファイルにインポートします。To use them, import wrappers.proto into your .proto file, like this:

syntax = "proto3"

import "google/protobuf/wrappers.proto"

message Person {

    ...
    google.protobuf.Int32Value age = 5;

}

Protobuf は、生成T?されたメッセージ プロパティint?に単純な ( など ) を使用します。Protobuf will use the simple T? (for example, int?) for the generated message property.

次の表は、同等の C# 型を持つラッパー型の完全な一覧を示しています。The following table shows the complete list of wrapper types with their equivalent C# type:

C# 型C# type よく知られている型ラッパーWell Known Type wrapper
double? google.protobuf.DoubleValue
float? google.protobuf.FloatValue
int? google.protobuf.Int32Value
long? google.protobuf.Int64Value
uint? google.protobuf.UInt32Value
ulong? google.protobuf.UInt64Value

よく知られている型TimestampDurationクラスとして .NET で表されます。The well-known types Timestamp and Duration are represented in .NET as classes. C# 8 以降では、null 許容参照型を使用できます。In C# 8 and beyond, you can use nullable reference types. しかし、これらの型のプロパティを null に変換する場合は、これらの型のプロパティDateTimeOffsetTimeSpanチェックすることが重要です。But it's important to check for null on properties of those types when you're converting to DateTimeOffset or TimeSpan.

10 進数Decimals

Protobuf は.NETdecimal型をdoubleネイティブにサポートしていません。 floatProtobuf doesn't natively support the .NET decimal type, just double and float. Protobuf プロジェクトでは、標準型をサポートする言語やフレームワークのプラットフォームサポートをDecimal使用して、既知の型に標準型を追加する可能性について、継続的な議論が行われています。There's an ongoing discussion in the Protobuf project about the possibility of adding a standard Decimal type to the well-known types, with platform support for languages and frameworks that support it. まだ何も実装されていません。Nothing has been implemented yet.

.NET クライアントとサーバー間の安全なシリアル化decimalに使用する型を表すメッセージ定義を作成できます。It's possible to create a message definition to represent the decimal type that would work for safe serialization between .NET clients and servers. しかし、他のプラットフォームの開発者は、使用されている形式を理解し、独自の処理を実装する必要があります。But developers on other platforms would have to understand the format being used and implement their own handling for it.

Protobuf のカスタム 10 進型の作成Creating a custom decimal type for Protobuf

単純な実装は、フィールドを使用しない一Money部の Google API が使用するcurrency非標準型に似ている可能性があります。A simple implementation might be similar to the nonstandard Money type that some Google APIs use, without the currency field.

package CustomTypes;

// Example: 12345.6789 -> { units = 12345, nanos = 678900000 }
message Decimal {

    // Whole units part of the amount
    int64 units = 1;

    // Nano units of the amount (10^-9)
    // Must be same sign as units
    sfixed32 nanos = 2;
}

このnanosフィールドは、0.999_999_999から-0.999_999_999から への値を表します。The nanos field represents values from 0.999_999_999 to -0.999_999_999. たとえば、decimal1.5m{ units = 1, nanos = 500_000_000 }として表されます。For example, the decimal value 1.5m would be represented as { units = 1, nanos = 500_000_000 }. この例のnanosフィールドでは、大きな値よりもsfixed32``int32効率的にエンコードされる型を使用するのはこのためです。This is why the nanos field in this example uses the sfixed32 type, which encodes more efficiently than int32 for larger values. フィールドがunits負の場合、nanosフィールドも負の値にする必要があります。If the units field is negative, the nanos field should also be negative.

注意

バイト文字列として値をエンコードdecimalするためのアルゴリズムは他に複数ありますが、このメッセージはそれらよりも理解しやすいです。There are multiple other algorithms for encoding decimal values as byte strings, but this message is easier to understand than any of them. 値は、異なるプラットフォームでのエンディアンの影響を受けません。The values are not affected by endianness on different platforms.

この型と BCLdecimal型の間の変換は、C# で次のように実装できます。Conversion between this type and the BCL decimal type might be implemented in C# like this:

namespace CustomTypes
{
    public partial class GrpcDecimal
    {
        private const decimal NanoFactor = 1_000_000_000;
        public GrpcDecimal(long units, int nanos)
        {
            Units = units;
            Nanos = nanos;
        }

        public long Units { get; }
        public int Nanos { get; }

        public static implicit operator decimal(CustomTypes.Decimal grpcDecimal)
        {
            return grpcDecimal.Units + grpcDecimal.Nanos / NanoFactor;
        }

        public static implicit operator CustomTypes.Decimal(decimal value)
        {
            var units = decimal.ToInt64(value);
            var nanos = decimal.ToInt32((value - units) * NanoFactor);
            return new CustomTypes.Decimal(units, nanos);
        }
    }
}

重要

このようなカスタム メッセージタイプを使用する場合は、常に.proto.Whenever you use custom message types like this, you must document them with comments in .proto. その後、他の開発者は、対応する型との変換を、独自の言語またはフレームワークで実装できます。Other developers can then implement conversion to and from the equivalent type in their own language or framework.