CLRの型

CLR (Common Language Runtime)
共通言語ランタイム
CLS (Common Language Specification)
共通言語仕様

事前定義型 (Predefined types)

値型 (Value types)

値型は、データを直接格納します。

  • 構造体 (Structs)
    • 数値型 (Numeric types)
      • 整数型 (Integral types)
      • 浮動小数点型 (Floating-point types)
      • decimal
    • ブール型 (Bool type)
  • 列挙型 (Enumerations)

null 許容型 (Nullable types)

特定の値型に対して、nullも受け入れるようにできます。

         int  a = null; // error CS0037: Null 非許容の値型であるため、Null を 'int' に変換できません

Nullable<int> b = null;
         int? c = null; // Nullable<T>の省略表現

値がnullであるかどうかは、HasValueの戻り値またはnullと比較することでわかります。

Nullable<int> x = null;
Console.Write(x.HasValue); // False
Console.Write(x == null);  // True

x = 10;
Console.Write(x.HasValue); // True
Console.Write(x.Value);    // 10

x = null;
Console.Write(x.Value); // System.InvalidOperationException「Null 許容のオブジェクトには値を指定しなければなりません。」

型がnull 許容型であるかどうかは、Nullable.GetUnderlyingType()がnullを返さないことで確認できます。c# - How to check if an object is nullable? - Stack Overflow

null許容型を基になる型へ変換するには、明示的なキャストが必要です。ただし値がnullのときにはInvalidOperationException例外が発生し失敗するため、null合体演算子を用いてnullの場合の値を明示します。

Nullable<int> x = null;

int a = x;       // error CS0266: 型 'int?' を 'int' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)
int b = (int)x;  // System.InvalidOperationException「Null 許容のオブジェクトには値を指定しなければなりません。」
int c = x ?? -1; // -1

参照型 (Reference types)

参照型は、データへの参照を格納します。

単純型 (Simple types)

単純型とは、コンパイラが直接サポートするデータ型です。この型は既存のFCLに直接マッピングされるため、次の4つのコードはすべて同一の結果をもたらします。

int          a = 0;
int          a = new int();

System.Int32 a = 0;
System.Int32 a = new System.Int32();
C#の型 FCLの型 CLS準拠 内容
bool System.Boolean trueまたはfalse
char System.Char 16ビット Unicode文字 (UTF-16)
sbyte System.SByte × 8ビット 符号付き整数値
byte System.Byte 8ビット 符号なし整数値
short System.Int16 16ビット 符号付き整数値
ushort System.UInt16 × 16ビット 符号なし整数値
int System.Int32 32ビット 符号付き整数値
uint System.UInt32 × 32ビット 符号なし整数値
long System.Int64 64ビット 符号付き整数値
ulong System.UInt64 × 64ビット 符号なし整数値
float System.Single 32ビット 浮動小数点型
double System.Double 64ビット 浮動小数点型
decimal System.Decimal 128ビット 浮動小数点型
組み込み型の一覧表 (C# リファレンス) | Microsoft Docs

参考

一意ではない型

匿名型 (Anonymous types)

型を明示せず、その決定をコンパイラに委ねます。

var i = 10;

dynamic型

コンパイラによる型チェックを回避できるobject型です。コンパイル時にはobject型に変換されるため、コンパイル時にのみ意味を持ちます。

型変換 (Type Conversions)

型変換の失敗は、コンパイル エラーとして検出されます。

int i = 10;
double d = i;

int i1 = d;      // error CS0266: 型 'double' を 'int' に暗黙的に変換できません。明示的な変換が存在します (cast が不足していないかどうかを確認してください)
int i2 = (int)d; // ok
string str = "sample";
int i1 = str;      // error CS0029: 型 'string' を 'int' に暗黙的に変換できません
int i2 = (int)str; // error CS0030: 型 'string' を 'int' に変換できません

派生型への変換など、実行時に型変換に失敗すると例外が投げられます。

object o = new object();
int i1 = (int)o; // System.InvalidCastException:指定されたキャストは有効ではありません。

int i = 10;
object o1 = i; // ok

安全な型変換

as演算子

変換可能ならば変換し、不可能ならば例外を投げずにnullを返します。as (C# リファレンス) | MSDN

expression as type

とすることは、次に同じです。

expression is type ? (type)expression : (type)null

変換不可能な場合を想定しないのならば、as演算子を用いず例外を投げさせます。

is演算子

指定の型に変換可能か調べられます。可能ならばtrue、さもなくばfalseが返されます。is (C# リファレンス) | MSDN

expression is type

この演算子は変換の可否を調べるだけの場合に用います。変換を伴う操作ならばas演算子で代用でき、is演算子で確認後に変換するような処理に対しては、CA1800として警告されます。ただしnull 非許容の型にはas演算子を適用できないため、この演算子を用います。

型変数のクラス

ボックス化 (ボクシング / boxing)

ボックス化とは、値型からobject型 (またはその値型によって実装されているインターフェイス型) への変換処理のことです。

ボックス化とボックス化解除 - C# プログラミング ガイド | Microsoft Docs

ボックス化解除 (アンボクシング / unboxing)

型の情報の取得

型の宣言の情報は、System.Typeクラスから取得できます。

Typeクラス

型の宣言の情報を表すクラスです。Type クラス (System) | Microsoft Docs

メンバの情報の取得

たとえば次のような型があるとすると、

public class MyClass
{
    private int field1;
    public int field2;

    public void Method1() { }

    public int Property1 { get; }
}

この型のTypeから、メンバの情報を取得できます。

public MemberInfo[] GetMembers()
Type.GetMembers メソッド (System) | Microsoft Docs

返されるメンバは、アルファベット順や宣言順などの特定の順番とはなりません。Remarks - Type.GetMembers Method (System)

Type type = typeof(MyClass);

System.Reflection.MemberInfo[] memberInfos = type.GetMembers(); // すべてのパブリック メンバ

System.Reflection.FieldInfo[] fieldInfos = type.GetFields();           // すべてのパブリック フィールド
System.Reflection.MethodInfo[] methodInfos = type.GetMethods();        // すべてのパブリック メソッド
System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties(); // すべてのパブリック プロパティ

Console.Write(fieldInfos[0].Name); // field2

さらに取得時にBindingFlags.NonPublicを指定すると非パブリックなメンバの情報も取得でき、これを介すとprivateなメンバへもアクセスできます。

MyClass obj = new MyClass();
// obj.field1 = 1; // error CS0122: 'MyClass.field1' はアクセスできない保護レベルになっています

FieldInfo field1 = type.GetField("field1", BindingFlags.NonPublic | BindingFlags.Instance);
field1.SetValue(obj, 1); // ok

Typeクラスのオブジェクトの取得

Typeクラスのオブジェクトは、次の方法により取得できます。

typeof演算子 (typeof expression)

型を指定して取得できます。typeof (C# リファレンス) | MSDN

Type type = typeof(int); // FullName = "System.Int32"

GetTypeメソッド

インスタンスから取得できます。Object.GetType Method (System) | Microsoft Docs

int a = 0;
Type type = a.GetType(); // FullName = "System.Int32"

または文字列から取得できます。Type.GetType Method (System) | Microsoft Docs

Type type = Type.GetType("System.Int32");

このとき文字列は、typeof(TypeNames).AssemblyQualifiedNameで得られるアセンブリ修飾名 (assembly-qualified name) で指定します。

Type.GetType("int");          // null
Type.GetType("Int32");        // null
Type.GetType("system.int32"); // null
Type.GetType("System.Int32"); // OK

型のサイズの取得

sizeof演算子

マネージド メモリに割り当てられたバイト数を取得できます。sizeof (C# リファレンス) | MSDN

int a1 = sizeof(int);   // 4
int a2 = sizeof(Int32); // 4

Marshal.SizeOfメソッド

アンマネージ オブジェクトのバイト数を取得できます。

public static int SizeOf(
    object structure
)
Marshal.SizeOf メソッド (Object) (System.Runtime.InteropServices) | MSDN

インスタンスのバイト単位のアンマネージ サイズを取得できます。

int x = 0;
int a = Marshal.SizeOf(x); // 4

オブジェクトから取得できるオーバーロードも用意されています。

int a1 = Marshal.SizeOf(typeof(int));
int a2 = Marshal.SizeOf<int>(); // .NET Framework 4.5.1 以降でサポート

参考

参考書

MSDN (Microsoft Developer Network) から検索