種類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_type s 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_type s について、既定値はすべてのゼロのビットパターンによって生成される値です。For all simple_type s, the default value is the value produced by a bit pattern of all zeros:
    • 、、、、、、、およびの場合 sbyte byte short ushort int uint long ulong 、既定値はに 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 の場合、既定値は、すべての値の型フィールドを既定値に設定し、すべての参照型フィールドをに設定することによって生成される値です nullFor 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. 次の例では、変数 i との j 両方がゼロに初期化されます。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). たとえば、 123 は型のリテラルで、 int 'a' は型のリテラルです charFor 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# では、、、、、、、、、およびの9つの整数型がサポートさ sbyte byte short ushort int uint long ulong れてい char ます。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 ます。ここで int 、は、 uint long 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. 単項 - 演算子を型のオペランドに適用することはできません ulongThe unary - operator cannot be applied to operands of type ulong.
  • 二項、、、、、、、、、、、、、、、、、、、、、およびの各演算子では、 + - * / オペランドは % & ^ | == != > < >= <= 型に変換され T T ます。ここで、は、、、、の最初の値で、 int uint long 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 ます。ここで、は、、、 int uint long 、および 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. 特に、型、型、および型には、 sbyte byte 型を ushort 使用して完全に表現できる値の範囲がありますが、、、 char またはからへの暗黙的な変換は sbyte 存在し byte 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_literal s として書き込むか、型へのキャストと組み合わせて integer_literal として記述する必要があり char ます。Constants of the char type must be written as character_literal s or as integer_literal s 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# では、との2つの浮動小数点型がサポートさ float れてい double ます。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:

  • 正のゼロと負のゼロ。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. 無限大は、ゼロ以外の数字をゼロで割るような演算で生成されます。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 は、ゼロをゼロで割るなど、無効な浮動小数点演算で生成されます。NaNs are produced by invalid floating-point operations, such as dividing zero by zero.
  • 形式の0以外の値の有限のセット s * m * 2^e ( s は1または-1)、 m およびは、 e 特定の浮動小数点型 float 0 < m < 2^24 -149 <= e <= 104 double 0 < m < 2^53 -1075 <= e <= 970 (、、およびの場合)、およびの場合はによって決まります。The 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 型は、概数から 5.0 * 10^-324 1.7 × 10^308 15-16 桁の有効桁数までの範囲の値を表すことができます。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. たとえば、一部のハードウェアアーキテクチャでは、型よりも範囲と有効桁数が大きい "拡張" または "long double" 浮動小数点型がサポートさ 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^-287.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 はに 0 <= e <= 28 なります。この 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. decimal 絶対値が未満の場合 1.0m 、値は28桁の小数点以下の桁数に完全になりますが、それ以上はありません。For decimals with an absolute value less than 1.0m, the value is exact to the 28th decimal place, but no further. decimal 絶対値が以上の場合 1.0m 、値は28または29の数字になります。For decimals with an absolute value greater than or equal to 1.0m, the value is exact to 28 or 29 digits. floatおよびデータ型とは対照的に double 、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. と表現では、 float double 多くの場合、このような数値は無限の分数であるため、これらの表現が丸められると、丸め誤差が発生しやすくなります。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 、演算の結果は0になります。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. 型の有効な値 booltrue 、と false です。The possible values of type bool are true and false.

と他の型の間に標準変換は存在しません boolNo 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. すべての列挙型には基になる型があり、これは、、、、、、またはである必要があり byte sbyte short ushort int uint long ulong ます。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? (any T )、および null 非許容値型 (つまり、制約を持つ任意の型パラメーター) として制約される任意の型パラメーターです structA 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

が true のインスタンス HasValue は、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.

が false のインスタンス HasValue は、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. ValueNull 許容のインスタンスのプロパティにアクセスするプロセスは、ラップ 解除と呼ばれます。The process of accessing the Value property of a nullable instance is referred to as unwrapping.

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

new T?(x)

プロパティがである、null 以外のインスタンスを作成し T? Value x ます。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_expression s (オブジェクト作成式) を使用して作成されます。Instances of class types are created using object_creation_expression s (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.ObjectThe 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.

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

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

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

  • との間の暗黙的な id 変換と、の object dynamic 置換時に同じである構築された型の間の暗黙的な 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.
  • の置換時に同じメソッドシグネチャ dynamic が同じ object シグネチャと見なされます。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 型は、から直接継承するシールクラス型です objectThe 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.StringThe 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_type の任意の値を型との間で変換できるようにすることで、 value_type s と reference_type の間のブリッジを提供し object ます。It provides a bridge between value_type s and reference_type s 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_typereference_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 参照が生成され、 null それ以外の場合は、基に HasValue false なる値のラップ解除とボックス化の結果が生成されます。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;
    }
}

型の値のボックス化 v T は、式 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がコンソールに出力されます。これは、の割り当てで暗黙のボックス化操作が行われ、 p box の値が 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. Pointは、代わりにとして宣言されてい class ます。値20が出力されます。これは、 p とが同じインスタンスを参照するため box です。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_typevalue_type に明示的に変換することを許可します。An unboxing conversion permits a reference_type to be explicitly converted to a value_type. 次のボックス化解除変換が存在します。The following unboxing conversions exist:

  • 型から object 任意の value_type にします。From the type object to any value_type.
  • 型から System.ValueType 任意の value_type にします。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_type にします。From any interface_type to any nullable_type whose underlying type implements the interface_type.
  • 型から System.Enum 任意の enum_type にします。From the type System.Enum to any enum_type.
  • 型から、 System.Enum 基になる enum_type を持つ任意の nullable_type にします。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 にボックス化を解除すると、ソースオペランドがの場合は nullable_type の null 値が生成され 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.

前のセクションで説明した架空のボックス化クラスを参照し、オブジェクトから value_type へのアンボックス変換は、式を実行することで box 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

すべての型は、*オープン型 _ または _ closed 型 * として分類できます。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. 制約を満たすには、型 AC 次のいずれかの方法で型に変換可能である必要があります。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 CAn 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.ValueTypeとは、 System.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.ValueTypeとは、 System.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() 、型をに A することはできず、 abstract パブリックなパラメーターなしのコンストラクターを持つ必要があります。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:

指定された型引数によって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. 次の例では、 D TT 基底クラスによって課される制約を満たすように、型パラメーターに制約を指定する必要があり B<T> ます。In 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>. これに対して、クラスは制約を指定する必要はあり E ません。これは、 List<T> IEnumerable に対してを実装するため T です。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

これらの代入の後、デリゲートは del を返すメソッドを参照し、 x + 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> には、 Compile 型のデリゲートを生成するインスタンスメソッドが用意されてい D ます。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);
    

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