6. 変換

''型変換'' は、異なる型を必要とするコンテキストで 1 つの型の値が使用される場合に実行されます。 このような変換が自動的に行われる場合、''暗黙的な変換'' と呼ばれます (この一般的な例として、オペランドによって指定された 1 つまたは複数の値を変換する必要があるいくつかの演算子があります)。変換時に数値の精度が失われないなど、ソース値の意味が保持される場合は、暗黙的な変換が許可されます。

キャスト演算子 (§7.2.9) では、''明示的な変換'' を行うことができます。

変換については以下で説明します。§6.19 の各演算子の説明では、必要に応じて補足情報が提供されます。

値を既に存在する型に明示的に変換した場合、その値や表現は変更されません。

式の値がパラメーターにバインドされるときの変換を処理するための規則については、§6.17 で説明します。

6.1 void への変換

void 型にキャストすることで、任意の型の値を明示的に破棄できます。 結果はありません。

6.2 bool への変換

bool 型に値を変換するための規則は次のとおりです。

  • 数値または char 値がゼロの場合は、False に変換されます。数値または char 値がゼロ以外の場合は、True に変換されます。
  • null 型の値は False に変換されます。
  • 長さが 0 の文字列は False に変換されます。長さが 0 を超える文字列は True に変換されます。
  • 値が $true のスイッチ パラメーターは True に変換され、値が $false のものは False に変換されます。
  • null 以外の他のすべての参照型の値は、True に変換されます。

型で IList を実装する場合:

  • オブジェクトの長さが 2 を超える場合、値は True に変換されます。
  • オブジェクトの長さが 1 で、最初の要素自体が IList ではなく、その要素の値が true の場合、値は True に変換されます。
  • それ以外の場合、最初の要素の Count が 1 以上の場合、値は True に変換されます。
  • それ以外の場合、値は False に変換されます。

6.3 char への変換

値を char 型に変換するための規則は次のとおりです。

  • bool、decimal、float、または double 型の値の変換はエラーになります。
  • null 型の値は、null (U+0000) 文字に変換されます。
  • 値を char 型で表すことができる整数型の値には、その値が含まれます。それ以外の場合、変換はエラーになります。
  • 長さが 1 以外の文字列値の変換はエラーになります。
  • 長さが 1 の文字列値は、その 1 文字の値を持つ char に変換されます。
  • 小数部を丸めた後の値を変換先の型で表すことができる数値型の値には、その丸められた値が含まれます。それ以外の場合、変換はエラーになります。
  • その他の参照型の値では、参照型でそのような変換がサポートされている場合、その変換が使用されます。それ以外の場合、変換はエラーになります。

6.4 integer への変換

byte、int、または long 型に値を変換するための規則は次のとおりです。

  • ブール値 False はゼロに変換されます。ブール値 True は 1 に変換されます。
  • 変換先の型で値を表すことができる char 型の値には、その値が含まれます。それ以外の場合、変換はエラーになります。
  • 小数部を丸めた後の値を変換先の型で表すことができる数値型の値には、その丸められた値が含まれます。それ以外の場合、変換はエラーになります。
  • null 型の値はゼロに変換されます。
  • §6.16 で説明されているように、数値を表す文字列は変換されます。 小数部が切り捨てられた後に、結果を変換先の型で表すことができる場合、文字列の形式は適切であり、変換先の型が含まれます。それ以外の場合、変換はエラーになります。 文字列が数値を表していない場合、変換はエラーになります。
  • その他の参照型の値では、参照型でそのような変換がサポートされている場合、その変換が使用されます。それ以外の場合、変換はエラーになります。

6.5 float および double への変換

float または double 型に値を変換するための規則は次のとおりです。

  • ブール値 False はゼロに変換されます。ブール値 True は 1 に変換されます。
  • char 値は正確に表されます。
  • 数値型の値は、可能であれば正確に表されます。しかし、int、long、および decimal から float への変換と、long および decimal から double への変換では、整数値の最下位ビットの一部が失われる可能性があります。
  • null 型の値はゼロに変換されます。
  • §6.16 で説明されているように、数値を表す文字列は変換されます。それ以外の場合、変換はエラーになります。
  • その他の参照型の値では、参照型でそのような変換がサポートされている場合、その変換が使用されます。それ以外の場合、変換はエラーになります。

6.6 decimal への変換

decimal 型に値を変換するための規則は次のとおりです。

  • ブール値 False はゼロに変換されます。ブール値 True は 1 に変換されます。
  • char 型の値は正確に表されます。
  • 数値型の値は正確に表されます。しかし、その値が大きすぎるか小さすぎて変換先の型に収まらない場合、変換はエラーになります。
  • null 型の値はゼロに変換されます。
  • §6.16 で説明されているように、数値を表す文字列は変換されます。それ以外の場合、変換はエラーになります。
  • その他の参照型の値では、参照型でそのような変換がサポートされている場合、その変換が使用されます。それ以外の場合、変換はエラーになります。
  • 正常な変換の結果のスケールは、小数部の末尾にゼロがないものになります。

6.7 object への変換

null 型 (4.1.2) を除く任意の型の値は、object 型に変換できます。 値の型と表現は保持されます。

6.8 sting への変換

string 型に値を変換する規則は次のとおりです。

  • ブール値 $false は "False" に変換されます。ブール値 $true は "True" に変換されます。
  • char 型の値は、その char を含む 1 文字の文字列に変換されます。
  • 数値型の値は、対応する数値リテラルの形式を持つ文字列に変換されます。 しかし、結果には先頭や末尾のスペースはなく、先頭のプラス記号はありません。整数には常用対数が含まれ、型サフィックスはありません。 10 進変換の場合は、スケールが保持されます。 -∞、+ ∞、および NaN の値の場合、結果の文字列はそれぞれ "-Infinity"、"Infinity"、および "NaN" になります。
  • null 型の値は、空の文字列に変換されます。
  • 1 次元配列の場合、結果は、その配列内の各要素の値を含む文字列であり、先頭から末尾まで文字列に変換され、要素は現在の出力フィールド区切り記号 (§2.3.2.2) で区切られます。 それ自体が配列である要素を含む配列の場合は、最上位要素のみが変換されます。 配列である要素の値を表すために使用される文字列は、実装定義です。 多次元配列の場合は、フラット化され (§9.12)、1 次元配列として扱われます。
  • null 型の値は、空の文字列に変換されます。
  • scriptblock 型の値は、区切り文字 { と } がない、そのブロックのテキストを含む文字列に変換されます。
  • 列挙型の値の場合、結果は、コンマで区切られ、その値でエンコードされた各列挙定数の名前を含む文字列になります。
  • その他の参照型の値では、参照型でそのような変換がサポートされている場合、その変換が使用されます。それ以外の場合、変換はエラーになります。

配列である要素の値を表すために使用される文字列は、System.type[]System.type[,] などの形式になります。 他の参照型の場合は、メソッド ToString が呼び出されます。 その他の列挙可能型の場合、ソース値は 1 次元配列のように扱われます。

6.9 array への変換

array 型に値を変換するための規則は次のとおりです。

  • ターゲット型が多次元配列ではない場合があります。
  • null 型の値はそのまま保持されます。
  • $null 以外のスカラー値または hashtable 型の値の場合、新しい 1 要素の配列が作成されます。その値は、ターゲット要素型への変換後にスカラーになります。
  • 1 次元配列値の場合、ターゲット型の新しい配列が作成され、各要素は、ソース配列からターゲット配列内の対応する要素に変換されてコピーされます。
  • 多次元配列値の場合、その配列は最初にフラット化され (§9.12)、1 次元配列値として扱われます。
  • 文字列値は、配列内の対応する位置を占有する文字列の後続の文字と同じ長さを持つ char の配列に変換されます。

その他の列挙型の場合、新しい 1 要素の配列が作成されます。その値は、ターゲット要素型への変換後に対応する要素となります (そのような変換が存在する場合)。 それ以外の場合、変換はエラーになります。

6.10 xml への変換

object は string 型に変換されてから、xml 型の XML ドキュメント オブジェクトに変換されます。

6.11 regex への変換

string 型の値を指定する式は、regex 型に変換される場合があります。

6.12 scriptblock への変換

値を scriptblock 型に変換するための規則は次のとおりです。

  • 文字列値は、必要に応じて、そのコマンドの呼び出しに対する引数の後に続くコマンドの名前として扱われます。

6.13 列挙型への変換

値を列挙型に変換するための規則は次のとおりです。

  • 列挙型の名前付き値 (大文字と小文字を区別) のいずれかを含む string 型の値は、その名前付き値に変換されます。
  • 列挙型の名前付き値 (大文字と小文字を区別) のコンマ区切りリストを含む string 型の値は、それらの名前付き値すべてのビット演算子 OR に変換されます。

6.14 他の参照型への変換

array 型や string 以外の参照型に値を変換するための規則は次のとおりです。

  • null 型の値はそのまま保持されます。
  • それ以外の場合、動作は実装定義となります。

ここでは多くの技法が使用されます。たとえば、単一の引数コンストラクターまたは既定のコンストラクター (値が hashtable の場合)、暗黙的および明示的な変換演算子、およびターゲット型では Parse メソッドが使用される可能性があります。また、Convert.ConvertTo や ETS 変換メカニズムが使用されます。

6.15 通常の算術変換

どのオペランドでも数値型の値が指定されていない場合は、次のようになります。

  • 左側のオペランドで bool 型の値が指定されている場合、変換はエラーになります。
  • それ以外の場合、$null 値を指定するすべてのオペランドは int 型のゼロに変換され、プロセスは以下に一覧表示されている数値変換に進みます。
  • それ以外の場合、左側のオペランドで char 型の値が指定され、右側のオペランドで bool 型の値が指定されている場合、変換はエラーになります。
  • それ以外の場合、左側のオペランドでは string 型の値が指定されているものの、数値 (§6.16) を表していない場合、変換はエラーになります。
  • それ以外の場合、右側のオペランドでは string 型の値が指定されているものの、数値 (§6.16) を表していない場合、変換はエラーになります。
  • それ以外の場合、string 型の値を指定しているすべてのオペランドは数値 (§6.16) に変換され、プロセスは以下に一覧表示されている数値変換に進みます。
  • それ以外の場合、変換はエラーになります。

数値変換:

  • 1 つのオペランドで decimal 型の値が指定されている場合、もう一方のオペランドによって指定された値は、必要に応じてその型に変換されます。 結果は decimal 型となります。
  • それ以外の場合、1 つのオペランドで double 型の値が指定されている場合、もう一方のオペランドによって指定された値は、必要に応じてその型に変換されます。 結果は double 型となります。
  • それ以外の場合、1 つのオペランドで float 型の値が指定されている場合、両方のオペランドによって指定された値は、必要に応じて double 型に変換されます。 結果は double 型となります。
  • それ以外の場合、1 つのオペランドで long 型の値が指定されている場合、もう一方のオペランド値よって指定された値は、必要に応じてその型に変換されます。 結果には、値を表すことができる、シーケンスlong および double に最初にその型が含まれます。
  • それ以外の場合、両方のオペランドによって指定された値は、必要に応じて int 型に変換されます。 結果には、切り捨てずに値を表すことができる、シーケンス int、long、double に最初のものが含まれます。

6.16 文字列から数値型への変換

文字列は、その内容に応じて、明示的または暗黙的に数値に変換することができます。 具体的には次のとおりです。

  • 空の文字列は、値 0 に変換されます。
  • 先頭と末尾のスペースは無視されます。しかし、文字列をスペースだけで構成することはできません。
  • 空白または行終端文字のみを含む文字列は、値ゼロに変換されます。
  • 先頭の + または - 記号が 1 つ許可されます。
  • 整数には、16 進数のプレフィックス (0x または 0X) が含まれる場合があります。
  • 必要に応じて、符号付き指数が許可されます。
  • 型サフィックスや乗数は許可されません。
  • 大文字と小文字を区別する文字列 "-Infinity"、"Infinity"、および "NaN" は、それぞれ -∞、+∞、および NaN の値として認識されます。

6.17 パラメーター バインド中の変換

パラメーター バインドの詳細については、§8.14 を参照してください。

式の値をパラメーターにバインドする場合は、以下で説明されているように、追加の変換に関する考慮事項があります。

  • パラメーターの型が bool または switch (§4.2.5§8.10.5) で、パラメーターに引数がない場合、呼び出されたコマンドのパラメーターの値は $true に設定されます。 パラメーターの型が bool や switch 以外の場合、引数のないパラメーターはエラーになります。
  • パラメーターの型が switch で、引数値が $null の場合、パラメーター値は $false に設定されます。
  • パラメーターの型が object であるか、引数の型と同じである場合、引数の値は変換されずに渡されます。
  • パラメーターの型が object や scriptblock ではない場合、scriptblock 型を持つ引数が評価され、その結果が引数の値として渡されます (これを 遅延スクリプト ブロック バインド と呼ぶ)。パラメーターの型が object または scriptblock の場合、scriptblock 型を持つ引数はそのまま渡されます。
  • パラメーターの型が T2 型のコレクションで、引数が T1 型のスカラーである場合、そのスカラーは 1 つの要素を含む T2 型のコレクションに変換されます。 必要に応じて、スカラー値は、このセクションの変換規則を使用して T2 型に変換されます。
  • パラメーターの型が object 以外のスカラー型で、引数がコレクションの場合、引数はエラーになります。
  • 予期されるパラメーター型が T2 型のコレクションで、引数が T1 型のコレクションである場合、引数は引数コレクションと同じ長さの T2 型のコレクションに変換されます。 必要に応じて、引数コレクション要素の値は、このセクションの変換規則を使用して T2 型に変換されます。
  • 上記の手順と、この章の前述の変換では不十分な場合、§6.18 の規則が適用されます。 それらが失敗した場合、パラメーターのバインドは失敗します。

6.18 .NET 変換

暗黙的な変換の場合、PowerShell の組み込み変換が最初に試されます。 変換を解決できない場合は、以下の .NET カスタム コンバーターが上から下の順に試されます。 変換が検出されても、例外がスローされている場合、変換は失敗しています。

  • PSTypeConverter: PSTypeConverter クラスの実装をそのターゲット クラスに関連付けるには、型構成ファイル (types.ps1xml) を使用するか、ターゲット クラスに System.ComponentModel.TypeConverterAttribute 属性を適用する 2 つの方法があります。 詳細については、PowerShell SDK のドキュメントを参照してください。

  • TypeConverter: この CLR 型では、標準値とサブプロパティにアクセスするためだけでなく、値の型を他の型に変換するための統一された方法が提供されます。 コンバーターの最も一般的な種類は、テキスト表現との間で変換するものです。 クラスの型コンバーターは、System.ComponentModel.TypeConverterAttribute を使用してクラスにバインドされます。 この属性がオーバーライドされない限り、このクラスから継承されるすべてのクラスにより、基本クラスと同じ型コンバーターが使用されます。 詳細については、PowerShell SDK および Microsoft .NET フレームワークのドキュメントを参照してください。

  • Parse メソッド: 変換元の型が string で、変換先の型に Parse というメソッドがある場合は、変換を実行するためにそのメソッドが呼び出されます。

  • コンストラクター: 変換先の型に、変換元の型を持つ 1 つの引数を取るコンストラクターがある場合、変換を実行するためにそのコンストラクターが呼び出されます。

  • 暗黙的なキャスト演算子: 変換元の型に、変換先の型に変換する暗黙的なキャスト演算子がある場合、変換を実行するためにその演算子が呼び出されます。

  • 明示的なキャスト演算子: 変換元の型に、変換先の型に変換する明示的なキャスト演算子がある場合、変換を実行するためにその演算子が呼び出されます。 変換先の型に、変換元の型から変換する明示的なキャスト演算子がある場合は、変換を実行するためにその演算子が呼び出されます。

  • IConvertable: 変換を実行するために System.Convert.ChangeType が呼び出されます。

6.19 ordered への変換

値を擬似型 ordered に変換するための規則は次のとおりです。

  • 値がハッシュ リテラル (§2.3.5.6) の場合、結果は、hashtable のように動作する実装定義型を持つオブジェクトであり、キーの順序はハッシュ リテラルで指定された順序と一致します。
  • それ以外の場合、動作は実装定義となります。

ordered に変換できるのは、ハッシュ リテラル (§2.3.5.6) のみです。 結果は System.Collections.Specialized.OrderedDictionary のインスタンスです。

6.20 pscustomobject への変換

値を擬似型 pscustomobject に変換するための規則は次のとおりです。

  • hashtable 型の値は、PowerShell オブジェクトに変換されます。 hashtable 内の各キーは、対応する値を持つ NoteProperty になります。
  • それ以外の場合、動作は実装定義となります。

変換は常に許可されますが、値の型は変更されません。