[OutSystems]ExtensionのC#コードに渡ってくるデータの型について

OutSystemsのExtension (C#) に渡したデータの型がどうなるかを確認してみました。
ドキュメントが見当たらなかったので、実際にコードを書いて確認した結果です。

# 環境
Personal Environment(Version 11.9.0 (Build 16900))
Service Studio(Version 11.8.8)
Integration Studio(Version 11.6.21)

# サンプルモジュール
[Forgeコンポーネント: HousesoftSampleExtension](https://www.outsystems.com/forge/component-overview/13723/housesoftsampleextension)のV1.0.2。
MainFlow > ClassInDotNet Screen

# 確認方法
ExtensionにObject型で引数を受け取り、C#内で型を調べて返すようにしました。
同時に、渡ってきたデータの種類の判別に使えそうな3つのInterface (C#) の実装状況も確認しています。

``` cs
public void MssCheckOSType(object ssInput, out string ssDataType, out bool ssIsIRecordAllocatable, out bool ssIsISimpleRecordAllocatable, out bool ssIsIOSListAllocatable) {
	var type = ssInput.GetType();
	ssDataType = type.FullName;
	ssIsIRecordAllocatable = typeof(IRecord).IsAssignableFrom(type);
	ssIsISimpleRecordAllocatable = typeof(ISimpleRecord).IsAssignableFrom(type);
	ssIsIOSListAllocatable = typeof(IOSList).IsAssignableFrom(type);
}
```

## C#内の型を調べる
Objectクラスから継承する、GetTypeメソッドを利用しています。
戻り値の型がTypeで、[FullNameプロパティ](https://docs.microsoft.com/ja-jp/dotnet/api/system.type?view=netframework-4.6.1#properties)で、名前空間を含めた完全修飾の型名を取得しています。

## Interfaceの実装を調べる
ardoJSONで利用していた方法です。実装を確認したいInterfaceに対して、typeof識別子を適用してType型のインスタンスを得る。
Type型のIsAssignableFromメソッドでパラメータに渡した値（この場合はActionのパラメータに渡したObject型の値）を該当Interfaceに割り当てられるか確認しています。

# 確認結果まとめ
「確認方法」に従って実際に調査した結果を表にしてみました。

| データの種類 | 型名 | IRecord | ISimpleRecord | IOSList |
|:-:|:--|:-:|:-:|:-:|
| 基本データ型：Text  | System.String  |   |   |   |
| 基本データ型：Decimal  | System.Decimal  |   |   |   |
| Structure：シンプル  | ssHousesoftSampleExtensionDemo.STSampleStructure  | ○  | ○  |   |
| Structure：子Structure有  | ssHousesoftSampleExtensionDemo.STSampleWithChildStructure  | ○  | ○  |   |
| Structure：Extensionに定義  | ssHousesoftSampleExtensionDemo.STSampleInExtensionStructure  | ○  | ○  |   |
| Entity：単独・１レコード  | ssHousesoftSampleExtensionDemo.ENSample_DepartmentEntityRecord  | ○  | ○  |   |
| Entity：単独・リスト  | ssHousesoftSampleExtensionDemo.RLSample_DepartmentRecordList  |   |   | ○  |
| Entity：ジョイン・１レコード  | ssHousesoftSampleExtensionDemo.RCSample_EmployeeSample_DepartmentRecord  | ○  |   |   |
| Entity：ジョイン・リスト  | ssHousesoftSampleExtensionDemo.RLSample_EmployeeSample_DepartmentRecordList  |   |   | ○  |
| Record：Data Type Editor  | ssHousesoftSampleExtensionDemo.RCTextSampleRecord  | ○  |   |   |

## 型
上の結果を観察すると、
- 基本データ型は、.NETの組み込み型のクラス表現を使っている様子
- 基本データ型以外のデータに対応するクラスは、「ss<呼び出し側モジュール名>」というフォーマットの名前空間に配置される
- Structureは「ST\<Structure名>Structure」というフォーマットのクラス名
- 単独Entityの1レコードは「EN\<Entity名>ENtityRecord」というフォーマットのクラス名
- ジョインしたクエリ結果の1レコードは「RC\<Entity名1>\<Entity名2>...Record」というフォーマットのクラス名
- Data Type Editorで編集した1レコードも似ていて、「RC\<構成要素のデータ型1>\<構成要素のデータ型2>...Record」というフォーマットのクラス名
- List型は「RL\<各レコードのクラス名>List」というフォーマットのクラス名

## Interface
上の結果を観察すると、
- リスト型であれば、個別レコードの型に関わらず、IOSListインターフェースのみ実装する
- 各レコードは、基本データ型なら3つのInterfaceのいずれも実装しない
- 基本データ型でないレコードはIRecordを実装する
- EntityやRecordはISimpleRecordを実装する。ただし、ジョインしたEntityと他のレコードを自分の要素に持つ場合は覗く

# 参考
公式ドキュメントとは少し違いますが、公式のコースの中に、Extensionで利用するデータの型について記述があります（資料のPDF）。
[C#コードでのロジックの拡張](https://www.outsystems.com/ja-jp/learn/lesson/1841/extending-logic-with-c-code)