すべての値型は、ボックス化と呼ばれるプロセスで参照型に変わることがあります。たとえば、オブジェクト参照を、binary-long などの値型に設定できます。ボックス化の際に、値がオブジェクト ヒープにコピーされ、参照がオブジェクト ヒープに戻されます。
ボックス化は、必要に応じて自動で行われます。たとえば、オブジェクトをパラメーターとして予測するメソッドに値型をパラメーターとして渡す場合などです。
明示的にボックス化するには、値型を汎用型 (.NET COBOL の System.Object や JVM COBOL の java.lang.Object など) に割り当てます。値型のボックス化を解除して、元の値型を復元できます。
データ項目の定義で TYPE classname を指定する場合:
ValueTypes のサンプルを参照してください。このサンプルは [[スタート > すべてのプログラム > Micro Focus Visual COBOL > Samples]] の [COBOL for .NET] にあります。
すべてのクラスにはルート オブジェクトが関連付けられています。このルート オブジェクトを使用して、そのフィールドやメソッドなどのクラスに関する情報を取得できます。型情報を取得するには、次の方法を使用します。
imperative-clause TYPE OF type-name
*>Value Types *>condition-value *>binary-char (unsigned) *>character *>binary-short, binary-long, binary-double (unsigned) *>float-short, float-long *>decimal *>DateTime (a framework type) *>Reference types *>object *>string *>Initializing declare correct as condition-value = true *> Can also infer variable type if the value has a well-defined type declare incorrect = false *> automatically a condition-value declare b as byte = h"2a" *> hex declare o as byte = o"52" *> octal declare b2 as byte = b"101010" *> binary declare person as object = null declare nam as string = "Dwight" declare grade as character = "B" declare now as type DateTime = type DateTime::Now *> No support for date/time literals declare amount as decimal = 35.99 declare gpa as float-short = 2.9 declare pi as float-long = 3.14159265 declare lTotal as binary-double = 123456 declare sTotal as binary-short = 123 declare usTotal as binary-short unsigned = 123 declare uiTotal as binary-long = 123 declare ulTotal as binary-long unsigned = 123 *>Type Information declare x as binary-long display x::GetType *> Prints System.Int32 display type of binary-long *> Prints System.Int32 display x::GetType::Name *> Prints Int32 *>Type Conversion declare f as float-short = 3.5 *> automatic conversion declare i = f as binary-long *> set to 3 (truncates decimal) end program. program-id Legacy. *> COBOL types not supported directly by other languages. *> Visual COBOL supports these types on all platforms. *> Only a few examples here 01 displayNumber pic 9(9).99. 01 computeNumber pic 9(9)V99. 01 alphaNumberic pic a(23). 01 binaryStorage pic x(12). *> Also groups and redefines - a few examples 01 arecord. 03 aSubRecord pic x(10). 03 aUnion pic 9(10) redefines aSubrecord. end program.
型変換では、ある型の式を別の型に変換できます。型変換には明示変換と暗黙変換の 2 種類があります。明示変換を実行するには、AS 指定または AS IF 指定を使用して変換後の型を指定する必要があります。この種類の変換の例を次に示します。
Declare myAnimal as type Animal Declare myWarthog as type Warthog … Set myWarthog to myAnimal as type Warthog *> Convert type Animal to type Warthog
この例では、Animal 型のすべてのオブジェクトが Warthog 型であるわけではないので明示変換が必要です。
Set myAnimal to myWarthog
Warthog 型は Animal 型から派生するため、変換は常に正当なものであり、暗黙的に行うことができます。同様に、暗黙変換を使用して、Animal 型のパラメーターを値によって渡すすべてのメソッドに引数として myWarthog を渡すことができます。
型 S から型 T への暗黙変換は、次の場合に許可されます。
01 appDomain type System.AppDomain. 01 obj object. 01 myList type List[string]. 01 myEnumerable type IEnumerable[string]. 01 objArray object occurs 10. 01 strArray string occurs 10. set obj to appDomain *> type System.AppDomain derives from System.Object set appDomain to obj *> produces compile time error set myEnumerable to myList *> List[string] implements IEnumerable[string] set objArray to strArray *> source element type derives from target element type
.NET COBOL では、どの値型も System.Object 型または System.ValueType 型のいずれかの参照型に変換できます。また、列挙型は System.Enum 型に変換できます。
JVM COBOL では、プリミティブ型をボックス化された型に次のように変換できます。シグネチャ S を持つ匿名メソッドは、同じシグネチャと戻り値の型を持つ任意のデリゲート型に変換できます。また、パラメーターのない匿名メソッドは、同じ戻り値の型を持つ任意のデリゲート型に変換できます。
メソッド名が method-name であるメソッド グループで、シグネチャが S で戻り値の型が R のデリゲート型に変換できるのは、そのメソッド グループ内に同じシグネチャと戻り値の型を持つメソッド (つまり、指定された名前のメソッド) がある場合です。
型 S から型 T への明示変換 (キャストとも呼ばれる) は、次の場合に許可されます。
キャストに失敗すると、例外がスローされます (.NET の場合は InvalidCastException、JVM の場合は ClassCastException)。これを避けるには、INSTANCE OF を使用して有効なキャストかどうかを最初にテストするか、例外ブロックでキャストをラップします (詳細は「TRY (試行) 文」を参照)。または、AS IF 指定を使用して、無効なキャストの場合はターゲット オブジェクトを null に設定して例外をスローしないように設定します (詳細は「式」を参照)。
明示参照変換の例を次に示します。01 appDomain type System.AppDomain. 01 obj object. 01 myList type List[string]. 01 myEnumerable type IEnumerable[string]. 01 objArray object occurs 10. 01 strArray string occurs 10. *> Following allowed as type System.AppDomain derives from object set appDomain to obj as type System.AppDomain *> Following allowed as list[string] implements IEnumerable[string] set myList to myEnumerable as type List[string] *> Following allowed as there exists an explicit reference conversion *> from object (the element type of objArray) to string (element type of strArray) set strArray to objArray as string occurs any *> explicit conversions can be used anywhere… display obj as type System.AppDomain set obj to type of object *> sets obj to a System.Type object *> The following will throw an exception set appDomain to obj as type System.AppDomain *> *> this statement does not fail, but sets myString to null *> set myString to myObject as if string実際に obj-object が System.Type インスタンスを参照している場合、obj-object が System.AppDomain インスタンスを参照すると断言すると、例外が次のようにスローされます。
*> these statements fail if uncommented *> set obj-object to obj-type *> set obj-app-domain to obj-object as type System.AppDomain
.NET COBOL では、System.Object 型または System.ValueType 型の項目を明示的に値型に変換できます。System.Enum 型の項目は列挙型に変換できます。
01 obj object. 01 dt type System.DateTime. Set obj to dt *> this is an implicit conversion using boxing Set dt to obj as type System.DateTime *> explicit unboxing conversionJVM COBOL では、次の型をプリミティブ型に変換できます。
変換演算子は、あるデータ型 (整数に定義した型など) のデータ項目を別のデータ型に変換します。変換演算子はオーバーロードできるため、適切な変換演算子が呼び出しコードのパラメーター型に従って使用されます。
暗黙変換の作成
たとえば、時間と分を含むタイプ Timer は、次の変換演算子を使用して binary-long として分に変換されます。
operator-id Implicit (a as type Timer) returning b as binary-long. set b to a::Hour * 60 + a::Minutes end operator.
この演算子は、次のような文で使用できます。
set myMins to timer3
同様に、次の変換演算子を使用して、binary-long データ項目 (分を表す) から、時間と分で表されるタイプ Timer に変換できます。
operator-id Implicit (a as binary-long) returning b as type Timer. set b to new Timer declare hour as binary-long = a / 60 set b::Hour to hour set b::Minutes to a - 60 * hour end operator.
この演算子は、次のような文で使用できます。
set timer4 to myMins
暗黙変換は、割り当てやメンバーの呼び出しなどのあらゆる場所で行われます。
暗黙変換は暗黙的または明示的に呼び出すことができます。たとえば、次の文はどちらも暗黙変換を呼び出します。
set myMins to timer3 set myMins to timer3 as binary-long
変換が信頼できる場合 (情報が失われず、例外がスローされない場合)、暗黙変換を使用します。
operator-id Explicit (a as String) returning b as type Timer. 01 strH String. 01 strM String. 01 colonPos binary-long value 0. set b to new Timer() set colonPos to a::IndexOf(":") try set strH to a::Substring(0 colonPos) set strM to a::Substring(colonPos + 1 2) set b::Hour to type Int32::Parse(strH) set b::Minutes to type Int32::Parse(strM) catch display "Invalid time format" end-try end operator.
明示変換は、変換後の型を明示的に提示する文でのみ行われます。たとえば、変換演算子が明示として定義される場合、次の 2 番目の文のみが機能します。
set timer4 to myString *> fails to compile as no implicit conversion exists set timer4 to myString as type Timer *> succeeds
変換で情報が失われたり、例外がスローされる可能性がある場合、(暗黙変換ではなく) 明示変換を使用します。上記の例では、文字列にテキストが含まれるか、何らかの理由で文字列が無効になります。この場合、失敗を処理するには try-catch ブロックが必要です。