種類Types

C#言語の型は、値型参照型の2つの主なカテゴリに分類されます。The types of the C# language are divided into two main categories: value types and reference types. 値型と参照型は、どちらも1つ以上の型パラメーターを受け取るジェネリック型にすることができます。Both value types and reference types may be generic types, which take one or more type parameters. 型パラメーターは、値型と参照型の両方を指定できます。Type parameters can designate both value types and reference types.

type
    : value_type
    | reference_type
    | type_parameter
    | type_unsafe
    ;

型の最後のカテゴリであるポインターは、アンセーフコードでのみ使用できます。The final category of types, pointers, is available only in unsafe code. これについては、「ポインター型」で詳しく説明します。This is discussed further in Pointer types.

値型は参照型とは異なり、値型の変数はデータを直接含んでいるのに対し、参照型の変数はデータへの参照を格納します。後者はオブジェクトと呼ばれます。Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. 参照型を使用すると、2つの変数が同じオブジェクトを参照する可能性があります。したがって、ある変数に対する操作が、もう一方の変数によって参照されるオブジェクトに影響を与える可能性があります。With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. 値型の場合、それぞれの変数にはデータの独自のコピーがあり、一方の変数に対する操作がもう一方に影響を与えることはできません。With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.

C#の型システムは、任意の型の値をオブジェクトとして扱うことができるように統合されています。C#'s type system is unified such that a value of any type can be treated as an object. C# における型はすべて、直接的または間接的に object クラス型から派生し、object はすべての型の究極の基底クラスです。Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. 参照型の値は、値を単純に object 型としてみなすことによってオブジェクトとして扱われます。Values of reference types are treated as objects simply by viewing the values as type object. 値型の値は、ボックス化とボックス化解除の操作 (ボックス化およびボックス化解除) を実行することで、オブジェクトとして扱われます。Values of value types are treated as objects by performing boxing and unboxing operations (Boxing and unboxing).

値型Value types

値型は、構造体型または列挙型のいずれかです。A value type is either a struct type or an enumeration type. C#単純型と呼ばれる定義済みの構造体型のセットを提供します。C# provides a set of predefined struct types called the simple types. 単純型は、予約語によって識別されます。The simple types are identified through reserved words.

value_type
    : struct_type
    | enum_type
    ;

struct_type
    : type_name
    | simple_type
    | nullable_type
    ;

simple_type
    : numeric_type
    | 'bool'
    ;

numeric_type
    : integral_type
    | floating_point_type
    | 'decimal'
    ;

integral_type
    : 'sbyte'
    | 'byte'
    | 'short'
    | 'ushort'
    | 'int'
    | 'uint'
    | 'long'
    | 'ulong'
    | 'char'
    ;

floating_point_type
    : 'float'
    | 'double'
    ;

nullable_type
    : non_nullable_value_type '?'
    ;

non_nullable_value_type
    : type
    ;

enum_type
    : type_name
    ;

参照型の変数とは異なり、値型の変数には、値の型が null 許容型である場合にのみ null 値を含めることができます。Unlike a variable of a reference type, a variable of a value type can contain the value null only if the value type is a nullable type. Null 非許容の値型ごとに、同じ値のセットと null値を示す、対応する null 許容値型があります。For every non-nullable value type there is a corresponding nullable value type denoting the same set of values plus the value null.

値型の変数への代入では、割り当てられている値のコピーが作成されます。Assignment to a variable of a value type creates a copy of the value being assigned. これは、参照によって識別されるオブジェクトではなく、参照をコピーする参照型の変数への代入とは異なります。This differs from assignment to a variable of a reference type, which copies the reference but not the object identified by the reference.

ValueType 型The System.ValueType type

すべての値型はクラス System.ValueTypeから暗黙的に継承します。このクラスはクラス objectから継承されます。All value types implicitly inherit from the class System.ValueType, which, in turn, inherits from class object. 型を値型から派生させることはできません。したがって、値型は暗黙的にシールされます (シールクラス)。It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (Sealed classes).

System.ValueType はそれ自体がvalue_typeではないことに注意してください。Note that System.ValueType is not itself a value_type. 代わりに、すべてのvalue_typeが自動的に派生するclass_typeです。Rather, it is a class_type from which all value_types are automatically derived.

既定のコンストラクターDefault constructors

すべての値型は、既定のコンストラクターと呼ばれる、パラメーターなしのパブリックなインスタンスコンストラクターを暗黙的に宣言します。All value types implicitly declare a public parameterless instance constructor called the default constructor. 既定のコンストラクターは、値型の既定値として認識される、ゼロで初期化されたインスタンスを返します。The default constructor returns a zero-initialized instance known as the default value for the value type:

  • すべてのsimple_types について、既定値は、すべてのゼロのビットパターンによって生成される値です。For all simple_types, the default value is the value produced by a bit pattern of all zeros:
    • sbytebyteshortushortintuintlongulongの場合、既定値は 0です。For sbyte, byte, short, ushort, int, uint, long, and ulong, the default value is 0.
    • charの場合、既定値は '\x0000'です。For char, the default value is '\x0000'.
    • floatの場合、既定値は 0.0fです。For float, the default value is 0.0f.
    • doubleの場合、既定値は 0.0dです。For double, the default value is 0.0d.
    • decimalの場合、既定値は 0.0mです。For decimal, the default value is 0.0m.
    • boolの場合、既定値は falseです。For bool, the default value is false.
  • Enum_type Eの場合、既定値は 0``E型に変換されます。For an enum_type E, the default value is 0, converted to the type E.
  • Struct_typeの既定値は、すべての値の型フィールドを既定値に設定し、すべての参照型フィールドを nullに設定することによって生成される値です。For a struct_type, the default value is the value produced by setting all value type fields to their default value and all reference type fields to null.
  • Nullable_typeの場合、既定値は HasValue プロパティが false で、Value プロパティが定義されていないインスタンスです。For a nullable_type the default value is an instance for which the HasValue property is false and the Value property is undefined. 既定値は null 許容型のnull 値とも呼ばれます。The default value is also known as the null value of the nullable type.

他のインスタンスコンストラクターと同様に、値型の既定のコンストラクターは new 演算子を使用して呼び出されます。Like any other instance constructor, the default constructor of a value type is invoked using the new operator. 効率上の理由から、実装によってコンストラクター呼び出しが生成されるようにするための要件はありません。For efficiency reasons, this requirement is not intended to actually have the implementation generate a constructor call. 次の例では、変数 ij がどちらも0に初期化されています。In the example below, variables i and j are both initialized to zero.

class A
{
    void F() {
        int i = 0;
        int j = new int();
    }
}

すべての値型には暗黙的にパラメーターなしのインスタンスコンストラクターがあるため、パラメーターなしのコンストラクターの明示的な宣言を struct 型に含めることはできません。Because every value type implicitly has a public parameterless instance constructor, it is not possible for a struct type to contain an explicit declaration of a parameterless constructor. ただし、構造体型では、パラメーター化されたインスタンスコンストラクター (コンストラクター) を宣言できます。A struct type is however permitted to declare parameterized instance constructors (Constructors).

構造体の型Struct types

構造体型は、定数、フィールド、メソッド、プロパティ、インデクサー、演算子、インスタンスコンストラクター、静的コンストラクター、および入れ子にされた型を宣言できる値型です。A struct type is a value type that can declare constants, fields, methods, properties, indexers, operators, instance constructors, static constructors, and nested types. 構造体型の宣言については、「 struct 宣言」を参照してください。The declaration of struct types is described in Struct declarations.

単純型Simple types

C#単純型と呼ばれる定義済みの構造体型のセットを提供します。C# provides a set of predefined struct types called the simple types. 単純型は予約語によって識別されますが、これらの予約語は、次の表で説明するように、System 名前空間の定義済みの構造体型のエイリアスにすぎません。The simple types are identified through reserved words, but these reserved words are simply aliases for predefined struct types in the System namespace, as described in the table below.

予約語Reserved word エイリアスを持つ型Aliased type
sbyte System.SByte
byte System.Byte
short System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
long System.Int64
ulong System.UInt64
char System.Char
float System.Single
double System.Double
bool System.Boolean
decimal System.Decimal

単純型は構造体型のエイリアスであるため、すべての単純型にメンバーが含まれます。Because a simple type aliases a struct type, every simple type has members. たとえば、int には System.Int32 で宣言されたメンバーと System.Objectから継承されたメンバーがあり、次のステートメントを使用できます。For example, int has the members declared in System.Int32 and the members inherited from System.Object, and the following statements are permitted:

int i = int.MaxValue;           // System.Int32.MaxValue constant
string s = i.ToString();        // System.Int32.ToString() instance method
string t = 123.ToString();      // System.Int32.ToString() instance method

単純型は、ある追加の操作を許可している点で、他の構造体型とは異なります。The simple types differ from other struct types in that they permit certain additional operations:

  • ほとんどの単純型では、リテラル(リテラル) を記述することによって値を作成できます。Most simple types permit values to be created by writing literals (Literals). たとえば、123int 型のリテラルで、'a'char型のリテラルです。For example, 123 is a literal of type int and 'a' is a literal of type char. C#は、一般に構造体型のリテラルのプロビジョニングを行いません。また、他の構造体型の既定以外の値は、最終的にこれらの構造体型のインスタンスコンストラクターを使用して作成されます。C# makes no provision for literals of struct types in general, and non-default values of other struct types are ultimately always created through instance constructors of those struct types.
  • 式のオペランドがすべて単純型定数である場合、コンパイラはコンパイル時に式を評価することができます。When the operands of an expression are all simple type constants, it is possible for the compiler to evaluate the expression at compile-time. このような式は、 constant_expression (定数式) と呼ばれます。Such an expression is known as a constant_expression (Constant expressions). 他の構造体型によって定義された演算子を含む式は、定数式とは見なされません。Expressions involving operators defined by other struct types are not considered to be constant expressions.
  • const 宣言を使用すると、単純型 (定数) の定数を宣言できます。Through const declarations it is possible to declare constants of the simple types (Constants). 他の構造体型の定数を使用することはできませんが、static readonly のフィールドでも同様の効果が得られます。It is not possible to have constants of other struct types, but a similar effect is provided by static readonly fields.
  • 単純型を含む変換は、他の構造体型によって定義された変換演算子の評価に参加できますが、ユーザー定義の変換演算子は、別のユーザー定義演算子の評価に参加することはできません (の評価ユーザー定義の変換)。Conversions involving simple types can participate in evaluation of conversion operators defined by other struct types, but a user-defined conversion operator can never participate in evaluation of another user-defined operator (Evaluation of user-defined conversions).

整数型Integral types

C#では、sbytebyteshortushortintuintlongulongcharの9つの整数型がサポートされています。C# supports nine integral types: sbyte, byte, short, ushort, int, uint, long, ulong, and char. 整数型には、次のサイズと値の範囲があります。The integral types have the following sizes and ranges of values:

  • sbyte 型は、-128 ~ 127 の値を持つ符号付き8ビット整数を表します。The sbyte type represents signed 8-bit integers with values between -128 and 127.
  • byte 型は、0 ~ 255 の値を持つ符号なし8ビット整数を表します。The byte type represents unsigned 8-bit integers with values between 0 and 255.
  • short 型は、-32768 ~ 32767 の値を持つ符号付き16ビット整数を表します。The short type represents signed 16-bit integers with values between -32768 and 32767.
  • ushort 型は、0 ~ 65535 の値を持つ符号なし16ビット整数を表します。The ushort type represents unsigned 16-bit integers with values between 0 and 65535.
  • int 型は、-2147483648 から2147483647までの値を持つ符号付き32ビット整数を表します。The int type represents signed 32-bit integers with values between -2147483648 and 2147483647.
  • uint 型は、0 ~ 4294967295 の値を持つ符号なし32ビット整数を表します。The uint type represents unsigned 32-bit integers with values between 0 and 4294967295.
  • long 型は、-9223372036854775808 ~ 9223372036854775807 の値を持つ符号付き64ビット整数を表します。The long type represents signed 64-bit integers with values between -9223372036854775808 and 9223372036854775807.
  • ulong 型は、0 ~ 18446744073709551615 の値を持つ符号なし64ビット整数を表します。The ulong type represents unsigned 64-bit integers with values between 0 and 18446744073709551615.
  • char 型は、0 ~ 65535 の値を持つ符号なし16ビット整数を表します。The char type represents unsigned 16-bit integers with values between 0 and 65535. char 型に使用できる値のセットは、Unicode 文字セットに対応しています。The set of possible values for the char type corresponds to the Unicode character set. char には ushortと同じ表現がありますが、1つの型で許可されているすべての操作が他方で許可されているわけではありません。Although char has the same representation as ushort, not all operations permitted on one type are permitted on the other.

整数型の単項演算子および二項演算子は、常に、符号付き32ビット精度、符号なし32ビット精度、符号付き64ビット精度、符号なし64ビット精度で動作します。The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:

  • 単項演算子 +~ 演算子の場合、オペランドは T型に変換されます。ここで、T は、オペランドのすべての使用可能な値を完全に表すことができる intuintlong、および ulong の最初のものです。For the unary + and ~ operators, the operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. この操作は T型の有効桁数を使用して実行され、結果の型は Tになります。The operation is then performed using the precision of type T, and the type of the result is T.
  • 単項 - 演算子では、オペランドが型 Tに変換されます。ここで、T は、オペランドのすべての可能な値を完全に表すことができる int および long の最初のものです。For the unary - operator, the operand is converted to type T, where T is the first of int and long that can fully represent all possible values of the operand. この操作は T型の有効桁数を使用して実行され、結果の型は Tになります。The operation is then performed using the precision of type T, and the type of the result is T. 単項 - 演算子を ulong型のオペランドに適用することはできません。The unary - operator cannot be applied to operands of type ulong.
  • バイナリ +-*/%&^|==!=><の各演算子では、オペランドは T型に変換されます。ここで、T は、両方のオペランドのすべての可能な値を完全に表すことができる intuintlong、および ulong の最初のものです。For the binary +, -, *, /, %, &, ^, |, ==, !=, >, <, >=, and <= operators, the operands are converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of both operands. この操作は T型の有効桁数を使用して実行され、結果の型は T になります (または、関係演算子の bool ます)。The operation is then performed using the precision of type T, and the type of the result is T (or bool for the relational operators). 1つのオペランドを long 型にし、もう一方のオペランドを二項演算子で ulong 型にすることは許可されていません。It is not permitted for one operand to be of type long and the other to be of type ulong with the binary operators.
  • 二項 << および >> 演算子の場合、左オペランドは T型に変換されます。ここで T は、オペランドのすべての可能な値を完全に表すことができる intuintlong、および ulong の最初のものです。For the binary << and >> operators, the left operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. この操作は T型の有効桁数を使用して実行され、結果の型は Tになります。The operation is then performed using the precision of type T, and the type of the result is T.

char 型は整数型として分類されますが、他の整数型とは次の2つの点で異なります。The char type is classified as an integral type, but it differs from the other integral types in two ways:

  • 他の型から char 型へと暗黙的に変換することはできません。There are no implicit conversions from other types to the char type. 特に、sbytebyte、および ushort 型には、char 型を使用して完全に表現できる値の範囲がある場合でも、sbytebyte、または ushort から char への暗黙的な変換は存在しません。In particular, even though the sbyte, byte, and ushort types have ranges of values that are fully representable using the char type, implicit conversions from sbyte, byte, or ushort to char do not exist.
  • char 型の定数は、 character_literals として記述するか、 integer_literalchar型へのキャストと組み合わせて使用する必要があります。Constants of the char type must be written as character_literals or as integer_literals in combination with a cast to type char. たとえば、(char)10'\x000A' と同じです。For example, (char)10 is the same as '\x000A'.

checked および unchecked の演算子とステートメントを使用して、整数型の算術演算および変換 (checked および unchecked 演算子) のオーバーフローチェックを制御します。The checked and unchecked operators and statements are used to control overflow checking for integral-type arithmetic operations and conversions (The checked and unchecked operators). checked コンテキストでは、オーバーフローによってコンパイル時エラーが生成されるか、System.OverflowException がスローされます。In a checked context, an overflow produces a compile-time error or causes a System.OverflowException to be thrown. unchecked のコンテキストでは、オーバーフローは無視され、変換先の型に収まらない上位ビットはすべて破棄されます。In an unchecked context, overflows are ignored and any high-order bits that do not fit in the destination type are discarded.

浮動小数点型Floating point types

C#では、floatdoubleの2つの浮動小数点型がサポートされています。C# supports two floating point types: float and double. float 型と double 型は、32ビットの単精度と64ビットの倍精度の IEEE 754 形式を使用して表されます。これにより、次の値のセットが提供されます。The float and double types are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats, which provide the following sets of values:

  • 正のゼロと負の0。Positive zero and negative zero. ほとんどの場合、正のゼロと負の0は単純な値ゼロと同じように動作しますが、特定の操作で2つの (除算演算子) が区別されます。In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two (Division operator).
  • 正の無限大と負の無限大。Positive infinity and negative infinity. 無限大は、0以外の数値を0で除算するなどの操作によって生成されます。Infinities are produced by such operations as dividing a non-zero number by zero. たとえば、1.0 / 0.0 は正の無限大を生成し、-1.0 / 0.0 は負の無限大を生成します。For example, 1.0 / 0.0 yields positive infinity, and -1.0 / 0.0 yields negative infinity.
  • の値。多くの場合、NaN が省略されています。The Not-a-Number value, often abbreviated NaN. Nan は、0除算などの無効な浮動小数点演算によって生成されます。NaNs are produced by invalid floating-point operations, such as dividing zero by zero.
  • s が1または-1 で、m および e が特定の浮動小数点型によって決定される、s * m * 2^e形式の0以外の値の有限のセット。 floatの場合は、0 < m < 2^24 の場合は -149 <= e <= 104double0 < m < 2^53 および -1075 <= e <= 970The finite set of non-zero values of the form s * m * 2^e, where s is 1 or -1, and m and e are determined by the particular floating-point type: For float, 0 < m < 2^24 and -149 <= e <= 104, and for double, 0 < m < 2^53 and -1075 <= e <= 970. 非正規化された浮動小数点数は、0以外の有効な値と見なされます。Denormalized floating-point numbers are considered valid non-zero values.

float 型は、有効桁数が7桁の、約 1.5 * 10^-45 から 3.4 * 10^38 までの範囲の値を表すことができます。The float type can represent values ranging from approximately 1.5 * 10^-45 to 3.4 * 10^38 with a precision of 7 digits.

double 型は、15-16 桁の有効桁数で、約 5.0 * 10^-324 から 1.7 × 10^308 までの範囲の値を表すことができます。The double type can represent values ranging from approximately 5.0 * 10^-324 to 1.7 × 10^308 with a precision of 15-16 digits.

二項演算子のオペランドの1つが浮動小数点型の場合、もう一方のオペランドは整数型または浮動小数点型である必要があり、演算は次のように評価されます。If one of the operands of a binary operator is of a floating-point type, then the other operand must be of an integral type or a floating-point type, and the operation is evaluated as follows:

  • オペランドの1つが整数型の場合、そのオペランドはもう一方のオペランドの浮動小数点型に変換されます。If one of the operands is of an integral type, then that operand is converted to the floating-point type of the other operand.
  • 次に、いずれかのオペランドが double型である場合、もう一方のオペランドが doubleに変換され、少なくとも double 範囲と有効桁数を使用して演算が実行され、結果の型が double (または関係演算子の bool) になります。Then, if either of the operands is of type double, the other operand is converted to double, the operation is performed using at least double range and precision, and the type of the result is double (or bool for the relational operators).
  • それ以外の場合は、少なくとも float 範囲と有効桁数を使用して演算が実行され、結果の型が float ます (または、関係演算子の bool)。Otherwise, the operation is performed using at least float range and precision, and the type of the result is float (or bool for the relational operators).

代入演算子を含む浮動小数点演算子は、例外を生成しません。The floating-point operators, including the assignment operators, never produce exceptions. 次に示すように、例外的な状況では、浮動小数点演算ではゼロ、無限大、または NaN が生成されます。Instead, in exceptional situations, floating-point operations produce zero, infinity, or NaN, as described below:

  • 浮動小数点演算の結果が変換先の形式に対して小さすぎる場合、演算の結果は正の0または負の0になります。If the result of a floating-point operation is too small for the destination format, the result of the operation becomes positive zero or negative zero.
  • 浮動小数点演算の結果が変換先の形式に対して大きすぎる場合、演算の結果は正の無限大または負の無限大になります。If the result of a floating-point operation is too large for the destination format, the result of the operation becomes positive infinity or negative infinity.
  • 浮動小数点演算が無効な場合、演算の結果は NaN になります。If a floating-point operation is invalid, the result of the operation becomes NaN.
  • 浮動小数点演算の一方または両方のオペランドが NaN の場合、演算の結果は NaN になります。If one or both operands of a floating-point operation is NaN, the result of the operation becomes NaN.

浮動小数点演算は、演算の結果の型よりも高い精度で実行される場合があります。Floating-point operations may be performed with higher precision than the result type of the operation. たとえば、一部のハードウェアアーキテクチャでは、double 型よりも範囲と有効桁数が大きい "拡張" または "long double" 浮動小数点型がサポートされており、このより高い有効桁数の型を使用してすべての浮動小数点演算が暗黙的に実行されます。For example, some hardware architectures support an "extended" or "long double" floating-point type with greater range and precision than the double type, and implicitly perform all floating-point operations using this higher precision type. このようなハードウェアアーキテクチャは、低精度で浮動小数点演算を実行し、パフォーマンスと精度の両方をプランするための実装を必要とするのでC#はなく、高いパフォーマンスを実現することだけが可能です。すべての浮動小数点演算に使用されます。Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. より正確な結果を提供する以外にも、測定可能な効果はほとんどありません。Other than delivering more precise results, this rarely has any measurable effects. ただし、x * y / zの形式の式では、乗算によって double 範囲外の結果が生成されますが、その後の除算では double 範囲に一時的な結果が返されます。これは、式がで評価されるという事実です。範囲の形式が大きいと、無限大ではなく、有限の結果が生成される可能性があります。However, in expressions of the form x * y / z, where the multiplication produces a result that is outside the double range, but the subsequent division brings the temporary result back into the double range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity.

Decimal 型The decimal type

decimal 型は 128 ビットのデータ型で、財務や通貨の計算に適しています。The decimal type is a 128-bit data type suitable for financial and monetary calculations. decimal 型は、1.0 * 10^-28 から 7.9 * 10^28 約28-29 の範囲の値を表すことができます。有効桁数はです。The decimal type can represent values ranging from 1.0 * 10^-28 to approximately 7.9 * 10^28 with 28-29 significant digits.

decimal 型の有限の値のセットは (-1)^s * c * 10^-e形式です。符号 s は0または1であり、c 係数は 0 <= *c* < 2^96によって指定され、小数点以下桁数は e になります。decimal 型は、符号付きの0、無限大、または NaN のをサポートしていません。The finite set of values of type decimal are of the form (-1)^s * c * 10^-e, where the sign s is 0 or 1, the coefficient c is given by 0 <= *c* < 2^96, and the scale e is such that 0 <= e <= 28.The decimal type does not support signed zeros, infinities, or NaN's. decimal は、10の累乗によってスケーリングされた96ビット整数として表されます。A decimal is represented as a 96-bit integer scaled by a power of ten. 1.0m未満の絶対値を持つ decimalの場合、値は28桁の小数点以下の桁数に完全になりますが、それ以上はありません。For decimals with an absolute value less than 1.0m, the value is exact to the 28th decimal place, but no further. 1.0m以上の絶対値を持つ decimals では、値は28桁または29桁になります。For decimals with an absolute value greater than or equal to 1.0m, the value is exact to 28 or 29 digits. データ型の floatdouble とは対照的に、0.1 のような10進数の小数部は、decimal 表現で正確に表すことができます。Contrary to the float and double data types, decimal fractional numbers such as 0.1 can be represented exactly in the decimal representation. floatdouble 表現では、多くの場合、このような数値は無限の分数になるため、これらの表現が丸められると、丸め誤差が発生しやすくなります。In the float and double representations, such numbers are often infinite fractions, making those representations more prone to round-off errors.

二項演算子のオペランドの1つが decimal型である場合、もう一方のオペランドは整数型または decimal型である必要があります。If one of the operands of a binary operator is of type decimal, then the other operand must be of an integral type or of type decimal. 整数型のオペランドが存在する場合は、演算が実行される前に decimal に変換されます。If an integral type operand is present, it is converted to decimal before the operation is performed.

decimal 型の値に対する演算の結果は、正確な結果 (各演算子に対して定義されているように、小数点以下桁数を保持します) を計算してから、その表現に合わせて丸めた結果になります。The result of an operation on values of type decimal is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. 結果は、最も近い表現可能な値に丸められます。また、結果が2つの表現可能な値に均等に近い場合は、最下位の桁に偶数の数値が含まれる値になります (これは "銀行型丸め" と呼ばれます)。Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as "banker's rounding"). ゼロの結果は、常に0の符号と小数点以下桁数が0になります。A zero result always has a sign of 0 and a scale of 0.

10進数の算術演算で、絶対値が絶対値で 5 * 10^-29 以下の値が生成された場合、演算の結果はゼロになります。If a decimal arithmetic operation produces a value less than or equal to 5 * 10^-29 in absolute value, the result of the operation becomes zero. decimal 算術演算によって、decimal 形式に対して大きすぎる結果が生成されると、System.OverflowException がスローされます。If a decimal arithmetic operation produces a result that is too large for the decimal format, a System.OverflowException is thrown.

decimal 型は、より精度が高く、浮動小数点型よりも範囲が小さくなっています。The decimal type has greater precision but smaller range than the floating-point types. したがって、浮動小数点型から decimal への変換ではオーバーフロー例外が発生する可能性があり、decimal から浮動小数点型への変換によって精度が失われる可能性があります。Thus, conversions from the floating-point types to decimal might produce overflow exceptions, and conversions from decimal to the floating-point types might cause loss of precision. このような理由から、浮動小数点型と decimalの間に暗黙的な変換は存在せず、明示的なキャストを行わないと、浮動小数点と decimal のオペランドを同じ式に混在させることはできません。For these reasons, no implicit conversions exist between the floating-point types and decimal, and without explicit casts, it is not possible to mix floating-point and decimal operands in the same expression.

Bool 型The bool type

bool 型はブール値の論理数を表します。The bool type represents boolean logical quantities. bool 型の有効な値は truefalseです。The possible values of type bool are true and false.

bool とその他の型の間に標準変換は存在しません。No standard conversions exist between bool and other types. 特に、bool 型は、整数型とは区別されていますが、整数値の代わりに bool 値を使用することはできません。その逆も同様です。In particular, the bool type is distinct and separate from the integral types, and a bool value cannot be used in place of an integral value, and vice versa.

C とC++言語では、ゼロの整数または浮動小数点値、または null ポインターをブール値 false、0以外の整数または浮動小数点値、または null 以外のポインターをブール値 trueに変換できます。In the C and C++ languages, a zero integral or floating-point value, or a null pointer can be converted to the boolean value false, and a non-zero integral or floating-point value, or a non-null pointer can be converted to the boolean value true. でC#は、整数または浮動小数点値を明示的に0に比較するか、オブジェクト参照を nullに明示的に比較することで、このような変換が行われます。In C#, such conversions are accomplished by explicitly comparing an integral or floating-point value to zero, or by explicitly comparing an object reference to null.

列挙型Enumeration types

列挙型は、名前付き定数を持つ別個の型です。An enumeration type is a distinct type with named constants. すべての列挙型には基になる型があり、bytesbyteshortushortintuintlongulongのいずれかである必要があります。Every enumeration type has an underlying type, which must be byte, sbyte, short, ushort, int, uint, long or ulong. 列挙型の値のセットは、基になる型の値のセットと同じです。The set of values of the enumeration type is the same as the set of values of the underlying type. 列挙型の値は、名前付き定数の値に制限されません。Values of the enumeration type are not restricted to the values of the named constants. 列挙型は列挙宣言 (列挙型宣言) を使用して定義されます。Enumeration types are defined through enumeration declarations (Enum declarations).

Null 許容型Nullable types

Null 許容型は、基になる型のすべての値と追加の null 値を表すことができます。A nullable type can represent all values of its underlying type plus an additional null value. Null 許容型は T?書き込まれます。 T は基になる型です。A nullable type is written T?, where T is the underlying type. この構文は System.Nullable<T>の短縮形であり、2つの形式を区別して使用できます。This syntax is shorthand for System.Nullable<T>, and the two forms can be used interchangeably.

逆に、 null 非許容の値型は、System.Nullable<T> 以外の任意の値型と、その短縮形 T? (任意の T) と、null 非許容の値型 (つまり、struct を持つ任意の型パラメーター) に制限されている任意の型パラメーターです。制約)。A non-nullable value type conversely is any value type other than System.Nullable<T> and its shorthand T? (for any T), plus any type parameter that is constrained to be a non-nullable value type (that is, any type parameter with a struct constraint). System.Nullable<T> 型は、T (型パラメーター制約) の値型の制約を指定します。これは、null 許容型の基になる型が null 非許容の値型であることを意味します。The System.Nullable<T> type specifies the value type constraint for T (Type parameter constraints), which means that the underlying type of a nullable type can be any non-nullable value type. Null 許容型の基になる型を null 許容型または参照型にすることはできません。The underlying type of a nullable type cannot be a nullable type or a reference type. たとえば、int??string? は無効な型です。For example, int?? and string? are invalid types.

Null 許容型 T? のインスタンスには、次の2つのパブリック読み取り専用プロパティがあります。An instance of a nullable type T? has two public read-only properties:

  • 型の HasValue プロパティ boolA HasValue property of type bool
  • 型の Value プロパティ TA Value property of type T

HasValue が true であるインスタンスは、null 以外であると言います。An instance for which HasValue is true is said to be non-null. Null 以外のインスタンスには既知の値が含まれており、Value その値を返します。A non-null instance contains a known value and Value returns that value.

HasValue が false であるインスタンスは、null と呼ばれます。An instance for which HasValue is false is said to be null. Null インスタンスには未定義の値が含まれています。A null instance has an undefined value. Null インスタンスの Value を読み取ろうとすると、System.InvalidOperationException がスローされます。Attempting to read the Value of a null instance causes a System.InvalidOperationException to be thrown. Null 許容インスタンスの Value プロパティにアクセスするプロセスを、ラップ解除と呼びます。The process of accessing the Value property of a nullable instance is referred to as unwrapping.

既定のコンストラクターに加えて、すべての null 許容型 T? には、T型の単一の引数を受け取るパブリックコンストラクターがあります。In addition to the default constructor, every nullable type T? has a public constructor that takes a single argument of type T. T型の値 x を指定した場合、フォームのコンストラクターが呼び出されます。Given a value x of type T, a constructor invocation of the form

new T?(x)

Value プロパティが xされる T? の null 以外のインスタンスを作成します。creates a non-null instance of T? for which the Value property is x. 指定された値の null 許容型の null 以外のインスタンスを作成するプロセスを、ラップと呼びます。The process of creating a non-null instance of a nullable type for a given value is referred to as wrapping.

暗黙の型変換は、null リテラルから、T? (Null リテラル変換) と T から T? (暗黙の null 許容型変換) から使用できます。Implicit conversions are available from the null literal to T? (Null literal conversions) and from T to T? (Implicit nullable conversions).

参照型Reference types

参照型は、クラス型、インターフェイス型、配列型、またはデリゲート型です。A reference type is a class type, an interface type, an array type, or a delegate type.

reference_type
    : class_type
    | interface_type
    | array_type
    | delegate_type
    ;

class_type
    : type_name
    | 'object'
    | 'dynamic'
    | 'string'
    ;

interface_type
    : type_name
    ;

array_type
    : non_array_type rank_specifier+
    ;

non_array_type
    : type
    ;

rank_specifier
    : '[' dim_separator* ']'
    ;

dim_separator
    : ','
    ;

delegate_type
    : type_name
    ;

参照型の値は、型のインスタンスへの参照 (後者はオブジェクトと呼ばれます) です。A reference type value is a reference to an instance of the type, the latter known as an object. null 特別な値は、すべての参照型と互換性があり、インスタンスが存在しないことを示します。The special value null is compatible with all reference types and indicates the absence of an instance.

クラス型Class types

クラス型は、データメンバー (定数とフィールド)、関数メンバー (メソッド、プロパティ、イベント、インデクサー、演算子、インスタンスコンストラクター、デストラクターおよび静的コンストラクター)、および入れ子にされた型を含むデータ構造を定義します。A class type defines a data structure that contains data members (constants and fields), function members (methods, properties, events, indexers, operators, instance constructors, destructors and static constructors), and nested types. クラス型は、派生クラスが基本クラスを拡張および特殊化できる機構である継承をサポートしています。Class types support inheritance, a mechanism whereby derived classes can extend and specialize base classes. クラス型のインスタンスは、 object_creation_expressions (オブジェクト作成式) を使用して作成されます。Instances of class types are created using object_creation_expressions (Object creation expressions).

クラス型については、「クラス」を参照してください。Class types are described in Classes.

次の表で説明するように、 C#定義済みの特定のクラス型は言語で特別な意味を持ちます。Certain predefined class types have special meaning in the C# language, as described in the table below.

クラスの型Class type 説明Description
System.Object 他のすべての型の最終的な基底クラス。The ultimate base class of all other types. オブジェクトの種類を参照してください。See The object type.
System.String C#言語の文字列型。The string type of the C# language. 文字列型を参照してください。See The string type.
System.ValueType すべての値型の基本クラス。The base class of all value types. ValueType 型を参照してください。See The System.ValueType type.
System.Enum すべての列挙型の基本クラス。The base class of all enum types. 列挙型」を参照してください。See Enums.
System.Array すべての配列型の基本クラス。The base class of all array types. 配列」を参照してください。See Arrays.
System.Delegate すべてのデリゲート型の基本クラス。The base class of all delegate types. デリゲート」を参照してください。See Delegates.
System.Exception すべての例外の種類の基本クラス。The base class of all exception types. 例外」を参照してください。See Exceptions.

オブジェクト型The object type

object クラス型は、他のすべての型の最終的な基本クラスです。The object class type is the ultimate base class of all other types. 内のすべてC#の型は、object クラス型から直接または間接的に派生します。Every type in C# directly or indirectly derives from the object class type.

キーワード object は、定義済みのクラス System.Objectのエイリアスにすぎません。The keyword object is simply an alias for the predefined class System.Object.

dynamic 型The dynamic type

dynamic 型 (objectなど) は任意のオブジェクトを参照できます。The dynamic type, like object, can reference any object. dynamic型の式に演算子を適用すると、その解決はプログラムが実行されるまで延期されます。When operators are applied to expressions of type dynamic, their resolution is deferred until the program is run. したがって、演算子を参照先のオブジェクトに合法的に適用できない場合、コンパイル中にエラーは発生しません。Thus, if the operator cannot legally be applied to the referenced object, no error is given during compilation. 代わりに、実行時に演算子の解決が失敗すると、例外がスローされます。Instead an exception will be thrown when resolution of the operator fails at run-time.

その目的は動的バインドを許可することです。これについては、「動的バインド」で詳しく説明します。Its purpose is to allow dynamic binding, which is described in detail in Dynamic binding.

dynamic は、次の点を除けば object と同一であると見なされます。dynamic is considered identical to object except in the following respects:

  • dynamic 型の式に対する演算は動的にバインドできます (動的バインド)。Operations on expressions of type dynamic can be dynamically bound (Dynamic binding).
  • 型の推定 (型の推論) では、両方が候補である場合、object よりも dynamic 優先されます。Type inference (Type inference) will prefer dynamic over object if both are candidates.

この等価性により、次のものが保持されます。Because of this equivalence, the following holds:

  • objectdynamic間の暗黙的な id 変換と、dynamic をに置き換えるときに同じである構築された型の間では、objectThere is an implicit identity conversion between object and dynamic, and between constructed types that are the same when replacing dynamic with object
  • object との間の暗黙の型変換と明示的な変換は、dynamicとの間でも適用されます。Implicit and explicit conversions to and from object also apply to and from dynamic.
  • dynamicobject に置き換える場合と同じメソッドシグネチャは、同じシグネチャと見なされます。Method signatures that are the same when replacing dynamic with object are considered the same signature
  • dynamic 型は、実行時に object と区別できません。The type dynamic is indistinguishable from object at run-time.
  • dynamic 型の式は、動的な式と呼ばれます。An expression of the type dynamic is referred to as a dynamic expression.

文字列型The string type

string 型は、objectから直接継承するシールクラス型です。The string type is a sealed class type that inherits directly from object. string クラスのインスタンスは、Unicode 文字列を表します。Instances of the string class represent Unicode character strings.

string 型の値は、文字列リテラル (文字列リテラル) として書き込むことができます。Values of the string type can be written as string literals (String literals).

キーワード string は、定義済みのクラス System.Stringのエイリアスにすぎません。The keyword string is simply an alias for the predefined class System.String.

インターフェイス型Interface types

インターフェイスはコントラクトを定義します。An interface defines a contract. インターフェイスを実装するクラスまたは構造体は、コントラクトに従う必要があります。A class or struct that implements an interface must adhere to its contract. インターフェイスは複数の基本インターフェイスから継承でき、クラスまたは構造体は複数のインターフェイスを実装できます。An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

インターフェイス型については、「インターフェイス」を参照してください。Interface types are described in Interfaces.

配列型Array types

配列は、計算されたインデックスを通じてアクセスされる0個以上の変数を含むデータ構造です。An array is a data structure that contains zero or more variables which are accessed through computed indices. 配列に含まれる変数は、配列の要素とも呼ばれ、すべて同じ型であり、この型は配列の要素型と呼ばれます。The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

配列型については、「配列」を参照してください。Array types are described in Arrays.

デリゲート型Delegate types

デリゲートは、1つ以上のメソッドを参照するデータ構造体です。A delegate is a data structure that refers to one or more methods. インスタンスメソッドの場合は、対応するオブジェクトインスタンスも参照します。For instance methods, it also refers to their corresponding object instances.

C またはC++のデリゲートに最も近いものは関数ポインターですが、関数ポインターで参照できるのは静的関数だけですが、デリゲートは静的メソッドとインスタンスメソッドの両方を参照できます。The closest equivalent of a delegate in C or C++ is a function pointer, but whereas a function pointer can only reference static functions, a delegate can reference both static and instance methods. 後者の場合、デリゲートは、メソッドのエントリポイントへの参照だけでなく、メソッドを呼び出すオブジェクトインスタンスへの参照も格納します。In the latter case, the delegate stores not only a reference to the method's entry point, but also a reference to the object instance on which to invoke the method.

デリゲート型については、「デリゲート」を参照してください。Delegate types are described in Delegates.

ボックス化とボックス化解除Boxing and unboxing

ボックス化とボックス化解除の概念はC#、型システムの中心となるものです。The concept of boxing and unboxing is central to C#'s type system. Value_types とreference_types の間のブリッジを提供します。これにより、 value_typeの任意の値を型 objectとの間で変換することが許可されます。It provides a bridge between value_types and reference_types by permitting any value of a value_type to be converted to and from type object. ボックス化とボックス化解除を使用すると、型システムの統一されたビューを使用して、任意の型の値を最終的にオブジェクトとして扱うことができます。Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object.

ボックス化変換Boxing conversions

ボックス化変換は、 value_typeを暗黙的にreference_typeに変換することを許可します。A boxing conversion permits a value_type to be implicitly converted to a reference_type. 次のボックス化変換が存在します。The following boxing conversions exist:

  • 任意のvalue_typeから型 objectにします。From any value_type to the type object.
  • 任意のvalue_typeから型 System.ValueTypeにします。From any value_type to the type System.ValueType.
  • 任意のnon_nullable_value_typeから、 value_typeによって実装されている任意のinterface_typeに。From any non_nullable_value_type to any interface_type implemented by the value_type.
  • 任意のnullable_typeから、基になるnullable_typeの型によって実装されている任意のinterface_typeにします。From any nullable_type to any interface_type implemented by the underlying type of the nullable_type.
  • 任意のenum_typeから型 System.Enumにします。From any enum_type to the type System.Enum.
  • 基になるenum_typeを持つ任意のnullable_typeから System.Enum型にします。From any nullable_type with an underlying enum_type to the type System.Enum.
  • 実行時に、型パラメーターからの暗黙的な変換が、値型から参照型 (型パラメーターを使用する暗黙的な変換) に変換される場合は、ボックス化変換として実行されることに注意してください。Note that an implicit conversion from a type parameter will be executed as a boxing conversion if at run-time it ends up converting from a value type to a reference type (Implicit conversions involving type parameters).

Non_nullable_value_typeの値をボックス化するには、オブジェクトインスタンスを割り当て、そのインスタンスにnon_nullable_value_type値をコピーします。Boxing a value of a non_nullable_value_type consists of allocating an object instance and copying the non_nullable_value_type value into that instance.

Nullable_typeの値をボックス化すると、null 値 (HasValuefalse) の場合は null 参照が生成され、それ以外の場合は、基になる値のラップ解除とボックス化の結果になります。Boxing a value of a nullable_type produces a null reference if it is the null value (HasValue is false), or the result of unwrapping and boxing the underlying value otherwise.

Non_nullable_value_typeの値をボックス化する実際のプロセスは、次のように宣言されているかのように動作するジェネリックボックス化クラスの存在を練りすることによって説明します。The actual process of boxing a value of a non_nullable_value_type is best explained by imagining the existence of a generic boxing class, which behaves as if it were declared as follows:

sealed class Box<T>: System.ValueType
{
    T value;

    public Box(T t) {
        value = t;
    }
}

T 型の値 v のボックス化は、式 new Box<T>(v)を実行し、結果のインスタンスを object型の値として返すようになりました。Boxing of a value v of type T now consists of executing the expression new Box<T>(v), and returning the resulting instance as a value of type object. したがって、ステートメントThus, the statements

int i = 123;
object box = i;

概念的に対応conceptually correspond to

int i = 123;
object box = new Box<int>(i);

上記の Box<T> のようなボックス化クラスは実際には存在せず、ボックス化された値の動的な型は実際にはクラス型ではありません。A boxing class like Box<T> above doesn't actually exist and the dynamic type of a boxed value isn't actually a class type. 代わりに、型 T のボックス化された値には動的な型 Tがあり、is 演算子を使用した動的な型チェックでは、単純に型 Tを参照できます。Instead, a boxed value of type T has the dynamic type T, and a dynamic type check using the is operator can simply reference type T. たとえば、オブジェクトに適用されたFor example,

int i = 123;
object box = i;
if (box is int) {
    Console.Write("Box contains an int");
}

は、文字列 "Box contains an int" をコンソールに出力します。will output the string "Box contains an int" on the console.

ボックス化変換は、ボックス化された値のコピーを作成することを意味します。A boxing conversion implies making a copy of the value being boxed. これは、 reference_typeから object型への変換とは異なります。この場合、値は引き続き同じインスタンスを参照し、objectより弱い派生型と見なされます。This is different from a conversion of a reference_type to type object, in which the value continues to reference the same instance and simply is regarded as the less derived type object. たとえば、次のように宣言したとします。For example, given the declaration

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

次のステートメントthe following statements

Point p = new Point(10, 10);
object box = p;
p.x = 20;
Console.Write(((Point)box).x);

は、値10をコンソールに出力します。これは、pbox に割り当てたときに暗黙的なボックス化操作によって p の値がコピーされるためです。will output the value 10 on the console because the implicit boxing operation that occurs in the assignment of p to box causes the value of p to be copied. pbox が同じインスタンスを参照するため、代わりに Point class として宣言されています。Had Point been declared a class instead, the value 20 would be output because p and box would reference the same instance.

ボックス化解除Unboxing conversions

アンボックス変換は、 reference_typeを明示的にvalue_typeに変換することを許可します。An unboxing conversion permits a reference_type to be explicitly converted to a value_type. 次のボックス化解除変換が存在します。The following unboxing conversions exist:

  • 型から任意のvalue_typeobject ます。From the type object to any value_type.
  • 型から任意のvalue_typeSystem.ValueType ます。From the type System.ValueType to any value_type.
  • 任意のinterface_typeから、 interface_typeを実装する任意のnon_nullable_value_typeに。From any interface_type to any non_nullable_value_type that implements the interface_type.
  • 任意のinterface_typeから、基になる型がinterface_typeを実装している任意のnullable_typeFrom any interface_type to any nullable_type whose underlying type implements the interface_type.
  • 型から任意のenum_typeSystem.Enum ます。From the type System.Enum to any enum_type.
  • 型から、基になるenum_typeを持つ任意のnullable_typeSystem.Enum ます。From the type System.Enum to any nullable_type with an underlying enum_type.
  • 実行時に参照型から値型に変換すると (明示的な動的変換)、型パラメーターへの明示的な変換は、アンボックス変換として実行されることに注意してください。Note that an explicit conversion to a type parameter will be executed as an unboxing conversion if at run-time it ends up converting from a reference type to a value type (Explicit dynamic conversions).

Non_nullable_value_typeへのボックス化解除操作では、最初に、オブジェクトインスタンスが指定されたnon_nullable_value_typeのボックス化された値であることを確認し、次にインスタンスから値をコピーします。An unboxing operation to a non_nullable_value_type consists of first checking that the object instance is a boxed value of the given non_nullable_value_type, and then copying the value out of the instance.

Nullable_typeにボックス化を解除すると、ソースオペランドが null場合はnullable_typeの null 値が生成されます。それ以外の場合は、オブジェクトインスタンスをnullable_typeの基になる型にボックス化解除した結果が返されます。Unboxing to a nullable_type produces the null value of the nullable_type if the source operand is null, or the wrapped result of unboxing the object instance to the underlying type of the nullable_type otherwise.

前のセクションで説明した架空のボックス化クラスを参照し、オブジェクト box からvalue_type T へのアンボックス変換は、((Box<T>)box).value式を実行することで構成されます。Referring to the imaginary boxing class described in the previous section, an unboxing conversion of an object box to a value_type T consists of executing the expression ((Box<T>)box).value. したがって、ステートメントThus, the statements

object box = 123;
int i = (int)box;

概念的に対応conceptually correspond to

object box = new Box<int>(123);
int i = ((Box<int>)box).value;

指定されたnon_nullable_value_typeへのアンボックス変換が実行時に成功するようにするには、ソースオペランドの値が、そのnon_nullable_value_typeのボックス化された値への参照である必要があります。For an unboxing conversion to a given non_nullable_value_type to succeed at run-time, the value of the source operand must be a reference to a boxed value of that non_nullable_value_type. ソースオペランドが null場合、System.NullReferenceException がスローされます。If the source operand is null, a System.NullReferenceException is thrown. ソースオペランドが互換性のないオブジェクトへの参照である場合は、System.InvalidCastException がスローされます。If the source operand is a reference to an incompatible object, a System.InvalidCastException is thrown.

指定されたnullable_typeへのアンボックス変換が実行時に成功するようにするには、source オペランドの値が null か、またはnullable_typeの基になるnon_nullable_value_typeのボックス化された値への参照である必要があります。For an unboxing conversion to a given nullable_type to succeed at run-time, the value of the source operand must be either null or a reference to a boxed value of the underlying non_nullable_value_type of the nullable_type. ソースオペランドが互換性のないオブジェクトへの参照である場合は、System.InvalidCastException がスローされます。If the source operand is a reference to an incompatible object, a System.InvalidCastException is thrown.

構築された型Constructed types

ジェネリック型の宣言自体は、型引数を適用することによって、さまざまな型を形成するための "ブループリント" として使用される、バインドされていないジェネリック型を表します。A generic type declaration, by itself, denotes an unbound generic type that is used as a "blueprint" to form many different types, by way of applying type arguments. 型引数は、ジェネリック型の名前の直後に山かっこ (<>) で記述されます。The type arguments are written within angle brackets (< and >) immediately following the name of the generic type. 少なくとも1つの型引数を含む型は、構築されたと呼ばれます。A type that includes at least one type argument is called a constructed type. 構築された型は、型名を表示できる言語のほとんどの場所で使用できます。A constructed type can be used in most places in the language in which a type name can appear. バインドされていないジェネリック型は、 typeof_expression (typeof 演算子) 内でのみ使用できます。An unbound generic type can only be used within a typeof_expression (The typeof operator).

構築された型は、単純な名前 (簡易名) として式で使用することも、メンバー (メンバーアクセス) にアクセスするときに使用することもできます。Constructed types can also be used in expressions as simple names (Simple names) or when accessing a member (Member access).

Namespace_or_type_nameが評価されると、正しい数の型パラメーターを持つジェネリック型だけが考慮されます。When a namespace_or_type_name is evaluated, only generic types with the correct number of type parameters are considered. したがって、型の型パラメーターの数が異なる限り、同じ識別子を使用して異なる型を識別することができます。Thus, it is possible to use the same identifier to identify different types, as long as the types have different numbers of type parameters. これは、ジェネリッククラスと非ジェネリッククラスを同じプログラムに混在させる場合に便利です。This is useful when mixing generic and non-generic classes in the same program:

namespace Widgets
{
    class Queue {...}
    class Queue<TElement> {...}
}

namespace MyApplication
{
    using Widgets;

    class X
    {
        Queue q1;            // Non-generic Widgets.Queue
        Queue<int> q2;       // Generic Widgets.Queue
    }
}

型パラメーターが直接指定されていない場合でも、 type_nameは構築された型を識別することがあります。A type_name might identify a constructed type even though it doesn't specify type parameters directly. これは、ジェネリッククラス宣言内で型が入れ子になっている場合に発生する可能性があり、包含する宣言のインスタンス型は、名前参照 (ジェネリッククラスの入れ子にされた型) に暗黙的に使用されます。This can occur where a type is nested within a generic class declaration, and the instance type of the containing declaration is implicitly used for name lookup (Nested types in generic classes):

class Outer<T>
{
    public class Inner {...}

    public Inner i;                // Type of i is Outer<T>.Inner
}

アンセーフコードでは、構築された型をunmanaged_type (ポインター型) として使用することはできません。In unsafe code, a constructed type cannot be used as an unmanaged_type (Pointer types).

型引数Type arguments

型引数リストの各引数は単なるです。Each argument in a type argument list is simply a type.

type_argument_list
    : '<' type_arguments '>'
    ;

type_arguments
    : type_argument (',' type_argument)*
    ;

type_argument
    : type
    ;

アンセーフコード (unsafe コード) では、 type_argumentをポインター型にすることはできません。In unsafe code (Unsafe code), a type_argument may not be a pointer type. それぞれの型引数は、対応する型パラメーター (型パラメーターの制約) に対する制約を満たす必要があります。Each type argument must satisfy any constraints on the corresponding type parameter (Type parameter constraints).

Open 型と closed 型Open and closed types

すべての型は、オープン型または閉じられた型として分類できます。All types can be classified as either open types or closed types. オープン型は、型パラメーターを含む型です。An open type is a type that involves type parameters. 具体的には次のようになります。More specifically:

  • 型パラメーターは、オープン型を定義します。A type parameter defines an open type.
  • 配列型は、要素型がオープン型である場合にのみ、オープン型になります。An array type is an open type if and only if its element type is an open type.
  • 構築された型は、型引数の1つ以上がオープン型である場合にのみ、オープン型になります。A constructed type is an open type if and only if one or more of its type arguments is an open type. 構築された入れ子になった型は、その型引数の1つ以上がオープン型である場合にのみ、オープン型になります。A constructed nested type is an open type if and only if one or more of its type arguments or the type arguments of its containing type(s) is an open type.

閉じられた型は、オープン型ではない型です。A closed type is a type that is not an open type.

実行時には、ジェネリック型宣言内のすべてのコードが、ジェネリック宣言に型引数を適用することによって作成されたクローズ構築型のコンテキストで実行されます。At run-time, all of the code within a generic type declaration is executed in the context of a closed constructed type that was created by applying type arguments to the generic declaration. ジェネリック型内の各型パラメーターは、特定の実行時の型にバインドされます。Each type parameter within the generic type is bound to a particular run-time type. すべてのステートメントおよび式の実行時処理は常に閉じられた型で発生し、オープン型はコンパイル時の処理中にのみ発生します。The run-time processing of all statements and expressions always occurs with closed types, and open types occur only during compile-time processing.

閉じられた構築型にはそれぞれ、静的な変数のセットがあります。これは、その他の閉じた構築型とは共有されません。Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types. オープン型は実行時に存在しないため、オープン型に関連付けられた静的変数はありません。Since an open type does not exist at run-time, there are no static variables associated with an open type. 2つの閉じられた構築型は、同じ非バインドジェネリック型から構築され、それらに対応する型引数が同じ型である場合、同じ型になります。Two closed constructed types are the same type if they are constructed from the same unbound generic type, and their corresponding type arguments are the same type.

バインドおよびバインド解除された型Bound and unbound types

バインドされていないとは、非ジェネリック型またはバインドされていないジェネリック型を指します。The term unbound type refers to a non-generic type or an unbound generic type. "バインドされた" とは、非ジェネリック型または構築された型を指します。The term bound type refers to a non-generic type or a constructed type.

バインドされていない型は、型宣言によって宣言されたエンティティを参照します。An unbound type refers to the entity declared by a type declaration. バインドされていないジェネリック型はそれ自体が型ではなく、変数、引数、または戻り値の型として、または基本型として使用することはできません。An unbound generic type is not itself a type, and cannot be used as the type of a variable, argument or return value, or as a base type. バインドされていないジェネリック型を参照できる唯一のコンストラクトは、typeof 式 (typeof 演算子) です。The only construct in which an unbound generic type can be referenced is the typeof expression (The typeof operator).

制約を満たすSatisfying constraints

構築された型またはジェネリックメソッドが参照されるたびに、指定された型引数は、ジェネリック型またはジェネリックメソッド (型パラメーターの制約) で宣言された型パラメーターの制約に照らしてチェックされます。Whenever a constructed type or generic method is referenced, the supplied type arguments are checked against the type parameter constraints declared on the generic type or method (Type parameter constraints). where 句ごとに、名前付きの型パラメーターに対応する型引数 A が、次のように各制約に対してチェックされます。For each where clause, the type argument A that corresponds to the named type parameter is checked against each constraint as follows:

  • 制約がクラス型、インターフェイス型、または型パラメーターである場合、C は、制約に含まれる型パラメーターの代わりに指定された型引数を持つ制約を表すことができます。If the constraint is a class type, an interface type, or a type parameter, let C represent that constraint with the supplied type arguments substituted for any type parameters that appear in the constraint. 制約を満たすには、型 A が、次のいずれかによって C 型に変換可能である必要があります。To satisfy the constraint, it must be the case that type A is convertible to type C by one of the following:
    • Id 変換 (id 変換)An identity conversion (Identity conversion)
    • 暗黙の参照変換 (暗黙的な参照変換)An implicit reference conversion (Implicit reference conversions)
    • 型 A が null 非許容の値型である場合、ボックス化変換 (ボックス化変換)。A boxing conversion (Boxing conversions), provided that type A is a non-nullable value type.
    • 型パラメーター A から Cへの暗黙的な参照、ボックス化、または型パラメーターの変換。An implicit reference, boxing or type parameter conversion from a type parameter A to C.
  • 制約が参照型制約 (class) の場合、型 A は次のいずれかを満たしている必要があります。If the constraint is the reference type constraint (class), the type A must satisfy one of the following:
    • A は、インターフェイス型、クラス型、デリゲート型、または配列型です。A is an interface type, class type, delegate type or array type. System.ValueTypeSystem.Enum は、この制約を満たす参照型であることに注意してください。Note that System.ValueType and System.Enum are reference types that satisfy this constraint.
    • A は、参照型 (型パラメーターの制約) であることがわかっている型パラメーターです。A is a type parameter that is known to be a reference type (Type parameter constraints).
  • 制約が値型制約 (struct) の場合、型 A は次のいずれかを満たしている必要があります。If the constraint is the value type constraint (struct), the type A must satisfy one of the following:
    • A は構造体型または列挙型ですが、null 許容型ではありません。A is a struct type or enum type, but not a nullable type. System.ValueTypeSystem.Enum は、この制約を満たしていない参照型であることに注意してください。Note that System.ValueType and System.Enum are reference types that do not satisfy this constraint.
    • A は、値型の制約 (型パラメーターの制約) を持つ型パラメーターです。A is a type parameter having the value type constraint (Type parameter constraints).
  • 制約がコンストラクターの制約 new()の場合は、型 Aabstract せずに、パブリックなパラメーターなしのコンストラクターを持つ必要があります。If the constraint is the constructor constraint new(), the type A must not be abstract and must have a public parameterless constructor. これは、次のいずれかに該当する場合に満たされます。This is satisfied if one of the following is true:
    • すべての値型にはパブリックな既定のコンストラクター (既定のコンストラクター) があるため、A は値型です。A is a value type, since all value types have a public default constructor (Default constructors).
    • A は、コンストラクターの制約 (型パラメーターの制約) を持つ型パラメーターです。A is a type parameter having the constructor constraint (Type parameter constraints).
    • A は、値型の制約 (型パラメーターの制約) を持つ型パラメーターです。A is a type parameter having the value type constraint (Type parameter constraints).
    • Aabstract ないクラスであり、パラメーターを持たない明示的に宣言された public コンストラクターを含んでいます。A is a class that is not abstract and contains an explicitly declared public constructor with no parameters.
    • Aabstract ではなく、既定のコンストラクター (既定のコンストラクター) を持っています。A is not abstract and has a default constructor (Default constructors).

指定された型引数によって1つ以上の型パラメーターの制約が満たされない場合、コンパイル時エラーが発生します。A compile-time error occurs if one or more of a type parameter's constraints are not satisfied by the given type arguments.

型パラメーターは継承されないため、制約は継承されません。Since type parameters are not inherited, constraints are never inherited either. 次の例では、T が基本クラス B<T>によって課される制約を満たすように、型パラメーター T に対して制約を指定する必要があり DIn the example below, D needs to specify the constraint on its type parameter T so that T satisfies the constraint imposed by the base class B<T>. 一方、List<T>TIEnumerable を実装しているため、クラス E では制約を指定する必要はありません。In contrast, class E need not specify a constraint, because List<T> implements IEnumerable for any T.

class B<T> where T: IEnumerable {...}

class D<T>: B<T> where T: IEnumerable {...}

class E<T>: B<List<T>> {...}

型パラメーターType parameters

型パラメーターは、実行時にパラメーターがバインドされる値型または参照型を指定する識別子です。A type parameter is an identifier designating a value type or reference type that the parameter is bound to at run-time.

type_parameter
    : identifier
    ;

型パラメーターは、さまざまな異なる実際の型引数を使用してインスタンス化できるため、型パラメーターには、他の型とは少し異なる操作と制限があります。Since a type parameter can be instantiated with many different actual type arguments, type parameters have slightly different operations and restrictions than other types. 次の設定があります。These include:

  • 型パラメーターを直接使用して基底クラス (基底クラス) またはインターフェイス (バリアント型パラメーターリスト) を宣言することはできません。A type parameter cannot be used directly to declare a base class (Base class) or interface (Variant type parameter lists).
  • 型パラメーターに対するメンバー参照の規則は、型パラメーターに適用される制約によって異なります。The rules for member lookup on type parameters depend on the constraints, if any, applied to the type parameter. これらの詳細については、「メンバー検索」を参照してください。They are detailed in Member lookup.
  • 型パラメーターに使用できる変換は、型パラメーターに適用される制約によって異なります。The available conversions for a type parameter depend on the constraints, if any, applied to the type parameter. これらの詳細については、型パラメーターと明示的な動的変換含む暗黙の型変換について説明します。They are detailed in Implicit conversions involving type parameters and Explicit dynamic conversions.
  • 型パラメーターが参照型であることがわかっている場合を除き、リテラル null を型パラメーターによって指定された型に変換することはできません (型パラメーターを使用する暗黙的な変換)。The literal null cannot be converted to a type given by a type parameter, except if the type parameter is known to be a reference type (Implicit conversions involving type parameters). ただし、代わりに default 式 (既定値の式) を使用できます。However, a default expression (Default value expressions) can be used instead. さらに、型パラメーターによって指定された型の値は、型パラメーターに値型の制約がない限り、==!= (参照型の等値演算子) を使用して、null と比較できます。In addition, a value with a type given by a type parameter can be compared with null using == and != (Reference type equality operators) unless the type parameter has the value type constraint.
  • new 式 (オブジェクト作成式) は、型パラメーターがconstructor_constraintまたは値型の制約 (型パラメーターの制約) によって制約されている場合にのみ、型パラメーターと共に使用できます。A new expression (Object creation expressions) can only be used with a type parameter if the type parameter is constrained by a constructor_constraint or the value type constraint (Type parameter constraints).
  • 型パラメーターは、属性内の任意の場所で使用することはできません。A type parameter cannot be used anywhere within an attribute.
  • 静的メンバーまたは入れ子にされた型を識別するために、型パラメーターをメンバーアクセス (メンバーアクセス) または型名 (名前空間と型名) で使用することはできません。A type parameter cannot be used in a member access (Member access) or type name (Namespace and type names) to identify a static member or a nested type.
  • アンセーフコードでは、型パラメーターをunmanaged_type (ポインター型) として使用することはできません。In unsafe code, a type parameter cannot be used as an unmanaged_type (Pointer types).

型として、型パラメーターは純粋にコンパイル時の構成要素です。As a type, type parameters are purely a compile-time construct. 実行時に、各型パラメーターは、ジェネリック型宣言に型引数を指定して指定されたランタイム型にバインドされます。At run-time, each type parameter is bound to a run-time type that was specified by supplying a type argument to the generic type declaration. したがって、型パラメーターを使用して宣言された変数の型は、実行時にクローズ構築型 (オープン型およびクローズ型) になります。Thus, the type of a variable declared with a type parameter will, at run-time, be a closed constructed type (Open and closed types). 型パラメーターを含むすべてのステートメントおよび式の実行時の実行では、そのパラメーターの型引数として指定された実際の型を使用します。The run-time execution of all statements and expressions involving type parameters uses the actual type that was supplied as the type argument for that parameter.

式ツリー型Expression tree types

式ツリーでは、ラムダ式を実行可能コードではなくデータ構造として表すことができます。Expression trees permit lambda expressions to be represented as data structures instead of executable code. 式ツリーは、System.Linq.Expressions.Expression<D>形式の式ツリー型の値です。 D は任意のデリゲート型です。Expression trees are values of expression tree types of the form System.Linq.Expressions.Expression<D>, where D is any delegate type. この仕様の残りの部分では、短縮形 Expression<D>を使用してこれらの型を参照します。For the remainder of this specification we will refer to these types using the shorthand Expression<D>.

ラムダ式から Dデリゲート型への変換が存在する場合、式ツリー型 Expression<D>にも変換されます。If a conversion exists from a lambda expression to a delegate type D, a conversion also exists to the expression tree type Expression<D>. ラムダ式からデリゲート型への変換では、ラムダ式の実行可能コードを参照するデリゲートが生成されますが、式ツリー型への変換では、ラムダ式の式ツリー表現が作成されます。Whereas the conversion of a lambda expression to a delegate type generates a delegate that references executable code for the lambda expression, conversion to an expression tree type creates an expression tree representation of the lambda expression.

式ツリーは、ラムダ式の効率的なインメモリデータ表現であり、ラムダ式の構造を透過的かつ明示的にします。Expression trees are efficient in-memory data representations of lambda expressions and make the structure of the lambda expression transparent and explicit.

デリゲート型 Dと同様に、Expression<D>Dのパラメーターと戻り値の型と同じように扱われます。Just like a delegate type D, Expression<D> is said to have parameter and return types, which are the same as those of D.

次の例は、ラムダ式を実行可能コードおよび式ツリーとして表しています。The following example represents a lambda expression both as executable code and as an expression tree. Func<int,int>への変換が存在するため、Expression<Func<int,int>>にも変換が存在します。Because a conversion exists to Func<int,int>, a conversion also exists to Expression<Func<int,int>>:

Func<int,int> del = x => x + 1;                    // Code

Expression<Func<int,int>> exp = x => x + 1;        // Data

これらの代入の後、デリゲート delx + 1を返すメソッドを参照し、式ツリー exp は式 x => x + 1を記述するデータ構造を参照します。Following these assignments, the delegate del references a method that returns x + 1, and the expression tree exp references a data structure that describes the expression x => x + 1.

ジェネリック型 Expression<D> の正確な定義と、ラムダ式が式ツリー型に変換されるときに式ツリーを構築するための正確な規則は、両方ともこの仕様の範囲外です。The exact definition of the generic type Expression<D> as well as the precise rules for constructing an expression tree when a lambda expression is converted to an expression tree type, are both outside the scope of this specification.

明示するには、次の2つのことが重要です。Two things are important to make explicit:

  • すべてのラムダ式を式ツリーに変換することはできません。Not all lambda expressions can be converted to expression trees. たとえば、ステートメント本体を含むラムダ式や、代入式を含むラムダ式を表すことはできません。For instance, lambda expressions with statement bodies, and lambda expressions containing assignment expressions cannot be represented. このような場合は、変換はまだ存在しますが、コンパイル時に失敗します。In these cases, a conversion still exists, but will fail at compile-time. これらの例外の詳細については、「匿名関数変換」を参考にしてください。These exceptions are detailed in Anonymous function conversions.

  • Expression<D> には、D型のデリゲートを生成するインスタンスメソッド Compile が用意されています。Expression<D> offers an instance method Compile which produces a delegate of type D:

    Func<int,int> del2 = exp.Compile();
    

    このデリゲートを呼び出すと、式ツリーによって表されるコードが実行されます。Invoking this delegate causes the code represented by the expression tree to be executed. したがって、上記の定義を指定した場合、del と del2 は同等であり、次の2つのステートメントは同じ効果を持ちます。Thus, given the definitions above, del and del2 are equivalent, and the following two statements will have the same effect:

    int i1 = del(1);
    
    int i2 = del2(1);
    

    このコードを実行すると、i1i2 の両方に 2値が設定されます。After executing this code, i1 and i2 will both have the value 2.