型 (C# プログラミング ガイド)Types (C# Programming Guide)

型、変数、および値Types, variables, and values

C# は、厳密に型指定された言語です。C# is a strongly typed language. すべての変数および定数は、値に評価されるすべての式がそうであるように、型を持ちます。Every variable and constant has a type, as does every expression that evaluates to a value. 各メソッドの宣言は、各入力パラメーターと戻り値に対して、名前、パラメーターの数、型と種類 (値、参照、または出力) を指定します。Every method declaration specifies a name, number of parameters, and type and kind (value, reference, or output) for each input parameter and for the return value. .NET クラス ライブラリでは、一連の組み込みの数値型が定義され、さらにファイル システム、ネットワーク接続、オブジェクトのコレクション、オブジェクトの配列、日付など、さまざまな論理構造を表すより複雑な型も定義されています。The .NET class library defines a set of built-in numeric types as well as more complex types that represent a wide variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and dates. 一般的な C# プログラムでは、クラス ライブラリで定義されている型と、そのプログラムの問題領域に固有の概念をモデル化するユーザー定義の型が使用されます。A typical C# program uses types from the class library as well as user-defined types that model the concepts that are specific to the program's problem domain.

型には、次のような情報が保存されます。The information stored in a type can include the following:

  • その型の変数が必要とする記憶領域。The storage space that a variable of the type requires.

  • 表すことができる最大値と最小値。The maximum and minimum values that it can represent.

  • 含まれるメンバー (メソッド、フィールド、イベントなど)。The members (methods, fields, events, and so on) that it contains.

  • 継承元となった基本型。The base type it inherits from.

  • 実行時に変数に割り当てられるメモリの場所。The location where the memory for variables will be allocated at run time.

  • 許可される演算の種類。The kinds of operations that are permitted.

コンパイラは型情報を使用して、コード内で実行されるすべての演算が "タイプ セーフ" であることを確認します。The compiler uses type information to make sure that all operations that are performed in your code are type safe. たとえば、int 型の変数を宣言すると、その変数は加算演算と減算演算で使用できます。For example, if you declare a variable of type int, the compiler allows you to use the variable in addition and subtraction operations. 同じ演算を bool 型の変数に対して実行しようとすると、コンパイラで次の例のようなエラーが発生します。If you try to perform those same operations on a variable of type bool, the compiler generates an error, as shown in the following example:

int a = 5;
int b = a + 2; //OK

bool test = true;

// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;


C や C++ と異なり、C# では、boolint に変換することはできません。C and C++ developers, notice that in C#, bool is not convertible to int.

コンパイラは、型情報を実行可能ファイル内にメタデータとして埋め込みます。The compiler embeds the type information into the executable file as metadata. 共通言語ランタイム (CLR: Common Language Runtime) は、実行時にこのメタデータを使用して、メモリの割り当て時および再要求時に、タイプ セーフであるかどうかを再度確認します。The common language runtime (CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.

変数宣言での型の指定Specifying types in variable declarations

プログラム内で変数や定数を宣言するときは、その型を指定するか、var キーワードを使用して、コンパイラが型を推論できるようにする必要があります。When you declare a variable or constant in a program, you must either specify its type or use the var keyword to let the compiler infer the type. 次の例では、組み込みの数値型と複雑なユーザー定義の型の両方を使用する変数宣言を示します。The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:

// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):
char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
            where item <= limit
            select item;

メソッドのパラメーターおよび戻り値の型は、メソッドの宣言で指定します。The types of method parameters and return values are specified in the method declaration. 入力引数として int を使用する必要があり、戻り値として文字列を返すメソッドのシグネチャを次に示します。The following signature shows a method that requires an int as an input argument and returns a string:

public string GetName(int ID)
    if (ID < names.Length)
        return names[ID];
        return String.Empty;
private string[] names = { "Spencer", "Sally", "Doug" };

変数を宣言すると、新しい型を使用してその変数を再度宣言することはできず、宣言された型と互換性のない値をその変数に代入することはできません。After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not compatible with its declared type. たとえば、int を宣言してから、それに true のブール値を代入することはできません。For example, you cannot declare an int and then assign it a Boolean value of true. ただし、たとえば新しい変数に代入するときや、メソッドの引数として渡すときに、値を他の型に変換することは可能です。However, values can be converted to other types, for example when they are assigned to new variables or passed as method arguments. データの損失を伴わない "型変換" は、コンパイラによって自動的に実行されます。A type conversion that does not cause data loss is performed automatically by the compiler. データの損失を伴う可能性のある変換には、ソース コードに cast を記述する必要があります。A conversion that might cause data loss requires a cast in the source code.

詳細については、「キャストと型変換」を参照してください。For more information, see Casting and Type Conversions.

組み込み型Built-in types

C# には、整数、浮動小数点値、ブール式、テキスト文字、10 進数値などのデータを表現するための標準的な組み込みの数値型が用意されています。C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. また、組み込みの string 型や object 型もあります。There are also built-in string and object types. これらの型は、すべての C# プログラムで使用できます。These are available for you to use in any C# program. 組み込み型の完全な一覧については、組み込みの型に関するページを参照してください。For the complete list of the built-in types, see Built-in types.

カスタム型Custom types

独自のカスタム型を作成するには、structclassinterface、および enum の各構造体を使用します。You use the struct, class, interface, and enum constructs to create your own custom types. .NET クラス ライブラリ自体が、マイクロソフトによって提供された、ユーザーが独自のアプリケーションで使用できるカスタムの型のコレクションです。The .NET class library itself is a collection of custom types provided by Microsoft that you can use in your own applications. 既定では、クラス ライブラリで最も頻繁に使用される型は任意の C# プログラムで使用可能になっています。By default, the most frequently used types in the class library are available in any C# program. その他の型は、その型が定義されているアセンブリへのプロジェクト参照を明示的に追加した場合にのみ使用可能になります。Others become available only when you explicitly add a project reference to the assembly in which they are defined. コンパイラがアセンブリを参照できるようになると、そのアセンブリ内で宣言されている型の変数 (および定数) をソース コード内で宣言できるようになります。After the compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that assembly in source code. 詳細については、「.NET クラス ライブラリの概要」を参照してください。For more information, see .NET Class Library.

共通型システムThe common type system

.NET で型システムを使用する場合は、次の 2 つの基本事項を理解しておく必要があります。It is important to understand two fundamental points about the type system in .NET:

  • 継承の原則がサポートされています。It supports the principle of inheritance. 他の型から型を派生させることができます。派生元の型は "基本型" と呼ばれます。Types can derive from other types, called base types. 派生した型は、基本型のメソッド、プロパティ、およびその他のメンバーを (若干の制限付きで) 継承します。The derived type inherits (with some restrictions) the methods, properties, and other members of the base type. 基本型もなんらかの他の型から派生できます。この場合、派生した型はその継承階層内の両方の基本型のメンバーを継承します。The base type can in turn derive from some other type, in which case the derived type inherits the members of both base types in its inheritance hierarchy. System.Int32 (C# のキーワードは int) などの組み込み数値型を含むすべての型は、最終的に System.Object (C# のキーワードは object) という単一の基本型から派生します。All types, including built-in numeric types such as System.Int32 (C# keyword: int), derive ultimately from a single base type, which is System.Object (C# keyword: object). この一元化された型階層は、共通型システム (CTS) と呼ばれます。This unified type hierarchy is called the Common Type System (CTS). C# での継承の詳細については、「継承」を参照してください。For more information about inheritance in C#, see Inheritance.

  • CTS の各型は、"値型" または "参照型" として定義されます。Each type in the CTS is defined as either a value type or a reference type. これは、.NET クラス ライブラリのすべてのカスタムの型や、ユーザーが独自に定義した型にも当てはまります。This includes all custom types in the .NET class library and also your own user-defined types. struct キーワードを使用して定義した型は値型であり、すべての組み込み数値型は structs です。Types that you define by using the struct keyword are value types; all the built-in numeric types are structs. class キーワードを使用して定義した型は、参照型です。Types that you define by using the class keyword are reference types. 参照型と値型では、コンパイル時の規則や実行時の動作が異なります。Reference types and value types have different compile-time rules, and different run-time behavior.

次の図は、CTS における値型と参照型の関係を示しています。The following illustration shows the relationship between value types and reference types in the CTS.

次の画像は、CTS の値の型と参照型を示しています。The following image shows value types and reference types in the CTS:

CTS の値の型と参照型を示すスクリーンショット。


この図を見るとわかるように、最もよく使用される型はすべて System 名前空間に属しています。You can see that the most commonly used types are all organized in the System namespace. しかし、型が属している名前空間は、その型が値型と参照型のどちらであるかには関係ありません。However, the namespace in which a type is contained has no relation to whether it is a value type or reference type.

値型Value types

値型は、System.ValueType の派生型である System.Object から派生します。Value types derive from System.ValueType, which derives from System.Object. System.ValueType から派生した型は、CLR では特殊な動作をします。Types that derive from System.ValueType have special behavior in the CLR. 値型の変数は、その値を直接含みます。つまり、変数がどのようなコンテキストで宣言されたとしても、必ずメモリがインラインで割り当てられます。Value type variables directly contain their values, which means that the memory is allocated inline in whatever context the variable is declared. 値型の変数には、独立したヒープ割り当てやガベージ コレクションのオーバーヘッドはありません。There is no separate heap allocation or garbage collection overhead for value-type variables.

値型には、構造体列挙体の 2 つのカテゴリがあります。There are two categories of value types: struct and enum.

組み込みの数値型は構造体であり、次のようにしてアクセスできるフィールドとメソッドを持ちます。The built-in numeric types are structs, and they have fields and methods that you can access:

// constant field on type byte.
byte b = byte.MaxValue;

ただし、宣言とそこへの値の代入は、あたかも単純な非集約型であるかのように行うことができます。But you declare and assign values to them as if they were simple non-aggregate types:

byte num = 0xA;
int i = 5;
char c = 'Z';

値型は、"シール" されています。たとえば System.Int32 から値型を派生させることはできません。構造体は System.ValueType しか継承できないため、任意のユーザー定義型または構造体を継承する構造体を定義することはできません。Value types are sealed, which means, for example, that you cannot derive a type from System.Int32, and you cannot define a struct to inherit from any user-defined class or struct because a struct can only inherit from System.ValueType. ただし、構造体は 1 つ以上のインターフェイスを実装できます。However, a struct can implement one or more interfaces. 構造体型は、実装する任意のインターフェイス型にキャストできます。これを行うと、"ボックス化操作" によって、構造体がマネージド ヒープ上の参照型オブジェクト内にラップされます。You can cast a struct type to any interface type that it implements; this causes a boxing operation to wrap the struct inside a reference type object on the managed heap. ボックス化操作が発生するのは、入力パラメーターとして System.Object または任意のインターフェイス型を受け取るメソッドに値型を渡した場合です。Boxing operations occur when you pass a value type to a method that takes a System.Object or any interface type as an input parameter. 詳細については、「ボックス化とボックス化解除」を参照してください。For more information, see Boxing and Unboxing.

独自のカスタム値型を作成するには、struct キーワードを使用します。You use the struct keyword to create your own custom value types. 通常、構造体は、次の例に示すように、少数の関連する変数のコンテナーとして使用します。Typically, a struct is used as a container for a small set of related variables, as shown in the following example:

public struct Coords
    public int x, y;

    public Coords(int p1, int p2)
        x = p1;
        y = p2;

構造体の詳細については、構造体型に関する記事をご覧ください。For more information about structs, see Structure types. 値型の詳細については、値型に関するページを参照してください。For more information about value types, see Value types.

別の種類の値型として、列挙体があります。The other category of value types is enum. 列挙体は、一連の名前付き整数定数を定義します。An enum defines a set of named integral constants. たとえば、.NET クラス ライブラリの System.IO.FileMode 列挙体には、ファイルを開く方法を指定する一連の名前付き整数定数が格納されています。For example, the System.IO.FileMode enumeration in the .NET class library contains a set of named constant integers that specify how a file should be opened. これは、次の例のように定義されます。It is defined as shown in the following example:

public enum FileMode
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,

定数 System.IO.FileMode.Create は、2 という値を持ちます。The System.IO.FileMode.Create constant has a value of 2. しかし、人間がソース コードを読む場合は名前があるとわかりやすいため、このような場合は、リテラルの数値の定数を使用するよりも、列挙体を使用する方がよいと言えます。However, the name is much more meaningful for humans reading the source code, and for that reason it is better to use enumerations instead of constant literal numbers. 詳細については、「System.IO.FileMode」を参照してください。For more information, see System.IO.FileMode.

すべての列挙体は、System.Enum の派生型である System.ValueType から派生します。All enums inherit from System.Enum, which inherits from System.ValueType. 構造体に適用されるすべての規則が、列挙体にも適用されます。All the rules that apply to structs also apply to enums. 詳細については、「列挙型」を参照してください。For more information about enums, see Enumeration types.

参照型Reference types

classdelegate、配列、または interface として定義された型は、"参照型" です。A type that is defined as a class, delegate, array, or interface is a reference type. 参照型の変数を宣言した場合、実行時には、new 演算子によってオブジェクトが明示的に作成されるまで、この変数には null が格納されます。または、次の例に示すように new を使用して、別の場所で作成されたオブジェクトを割り当てることもできます。At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an object by using the new operator, or assign it an object that has been created elsewhere by using new, as shown in the following example:

MyClass mc = new MyClass();
MyClass mc2 = mc;

インターフェイスは、それを実装するクラス オブジェクトで一緒に初期化する必要があります。An interface must be initialized together with a class object that implements it. MyClassIMyInterface を実装している場合は、次の例のようにして IMyInterface のインスタンスを作成できます。If MyClass implements IMyInterface, you create an instance of IMyInterface as shown in the following example:

IMyInterface iface = new MyClass();

オブジェクトが作成されると、マネージド ヒープ上でメモリが割り当てられ、変数にはそのオブジェクトの場所への参照のみが格納されます。When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. マネージド ヒープを使用する型では、メモリの割り当て時と、CLR の自動メモリ管理機能 ("ガベージ コレクション") による再要求時の両方についてオーバーヘッドが発生します。Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage collection. しかし、ガベージ コレクションも高度に最適化されるため、ほとんどのシナリオでは、パフォーマンス上の問題が発生することはありません。However, garbage collection is also highly optimized, and in most scenarios it does not create a performance issue. ガベージ コレクションの詳細については、「自動メモリ管理」を参照してください。For more information about garbage collection, see Automatic Memory Management.

配列は、その要素が値型の場合でも、すべて参照型です。All arrays are reference types, even if their elements are value types. 配列は、System.Array クラスから暗黙的に派生しますが、C# に用意されている次の例のような簡単な構文で宣言および使用します。Arrays implicitly derive from the System.Array class, but you declare and use them with the simplified syntax that is provided by C#, as shown in the following example:

// Declare and initialize an array of integers.
int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.
int len = nums.Length;

参照型では、継承が全面的にサポートされています。Reference types fully support inheritance. クラスの作成時には、シール クラスとして定義されているものを除く、他のすべてのインターフェイスまたはクラスから継承できます。また、作成したクラスから他のクラスを継承し、仮想メソッドをオーバーライドすることもできます。When you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes can inherit from your class and override your virtual methods. 独自のクラスを作成する方法の詳細については、「クラスおよび構造体」を参照してください。For more information about how to create your own classes, see Classes and Structs. 継承と仮想メソッドの詳細については、「継承」を参照してください。For more information about inheritance and virtual methods, see Inheritance.

リテラル値の型Types of literal values

C# では、リテラル値の型がコンパイラによって決定されます。In C#, literal values receive a type from the compiler. 数値リテラルの型指定の方法を指定するには、その数値の末尾に文字を付加します。You can specify how a numeric literal should be typed by appending a letter to the end of the number. たとえば、値 4.56 を float 型として扱うには、数値の後に "f" または "F" を付加して、4.56f のように指定します。For example, to specify that the value 4.56 should be treated as a float, append an "f" or "F" after the number: 4.56f. 文字を付加しない場合、リテラルの型はコンパイラによって推論されます。If no letter is appended, the compiler will infer a type for the literal. 文字サフィックスで指定できる型の詳細については、「整数数値型」と「浮動小数点数値型」を参照してください。For more information about which types can be specified with letter suffixes, see Integral numeric types and Floating-point numeric types.

リテラルは型指定され、すべての型は最終的に System.Object から派生するため、次のようなコードを記述してコンパイルできます。Because literals are typed, and all types derive ultimately from System.Object, you can write and compile code such as the following:

string s = "The answer is " + 5.ToString();
// Outputs: "The answer is 5"

Type type = 12345.GetType();
// Outputs: "System.Int32"

ジェネリック型Generic types

クライアント コードが型のインスタンスを作成したときに提供される実際の型 (具象型) のプレースホルダーとして使用される 1 つ以上の型パラメーターで、型を宣言することもできます。A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the concrete type) that client code will provide when it creates an instance of the type. このような型は、ジェネリック型と呼ばれます。Such types are called generic types. たとえば、.NET の型 System.Collections.Generic.List<T> には、慣例により T という名前が与えられる 1 つの型パラメーターがあります。この型のインスタンスを作成するときには、たとえば文字列の場合なら、リストに含まれるオブジェクトの型を次のように指定します。For example, the .NET type System.Collections.Generic.List<T> has one type parameter that by convention is given the name T. When you create an instance of the type, you specify the type of the objects that the list will contain, for example, string:

List<string> stringList = new List<string>();
stringList.Add("String example");
// compile time error adding a type other than a string:

型パラメーターを使用することで、同じクラスを再利用して任意の型の要素を格納できます。このとき、各要素をオブジェクトに変換する必要はありません。The use of the type parameter makes it possible to reuse the same class to hold any type of element, without having to convert each element to object. ジェネリック コレクション クラスが "厳密に型指定されたコレクション" と呼ばれるのは、コレクションの要素の固有の型をコンパイラが認識しているためで、たとえば、前の例の stringList オブジェクトに整数を追加しようとすると、コンパイル時にエラーが発生します。Generic collection classes are called strongly typed collections because the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for example, you try to add an integer to the stringList object in the previous example. 詳細については、「ジェネリック」を参照してください。For more information, see Generics.

暗黙の型、匿名型、および Null 許容値型Implicit types, anonymous types, and nullable value types

前にも説明したとおり、ローカル変数 (クラスのメンバーではない) の型を暗黙的に指定するには、var キーワードを使用します。As stated previously, you can implicitly type a local variable (but not class members) by using the var keyword. 変数の型はコンパイル時に決定されますが、その型はコンパイラによって指定されます。The variable still receives a type at compile time, but the type is provided by the compiler. 詳細については、「暗黙的に型指定されるローカル変数」を参照してください。For more information, see Implicitly Typed Local Variables.

場合によっては、メソッドの境界を越えて格納したり受け渡したりする予定のない単純な一連の関連値に名前付きの型を作成するのは便利ではないこともあります。In some cases, it is inconvenient to create a named type for simple sets of related values that you do not intend to store or pass outside method boundaries. このような場合は、"匿名型" を作成できます。You can create anonymous types for this purpose. 詳細については、「匿名型」を参照してください。For more information, see Anonymous Types.

値型には、通常、null 値を割り当てることができません。Ordinary value types cannot have a value of null. しかし、型の後ろに ? を付けることによって、null 値を設定できる値型を作成できます。However, you can create nullable value types by affixing a ? after the type. たとえば、int? は、null 値も設定できる int 型です。For example, int? is an int type that can also have the value null. Null 許容値型は一般的な構造体型 System.Nullable<T> のインスタンスです。Nullable value types are instances of the generic struct type System.Nullable<T>. Null 許容値型は、数値が null になる可能性のあるデータベースとの間でデータを受け渡しする場合に、特に便利です。Nullable value types are especially useful when you are passing data to and from databases in which numeric values might be null. 詳細については、「Null 許容値型」を参照してください。For more information, see Nullable value types.

詳細については、次のトピックを参照してください。For more information, see the following topics:

C# 言語仕様C# language specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

関連項目See also