Embarcadero Prism の Oxygene言語 と C# の比較

By: Tomohiro Takahashi

Abstract: この記事では、C#には用意されていない、Embarcadero Prismで利用可能な言語機能について解説します

以下の情報は、Oxygene Language Wiki でも参照可能です。

Embarcadero Prism(Oxygene) と C# の大きな違いとして、例えば、Delphi for Win32 のスキルを持つ開発者には非常に魅力的な Object Pascal ベースの構文が挙げられます。ただし、コンパイラによって追加された非常に便利なさまざまな追加機能もあります。

次の表は、Embarcadero Prism(Oxygene)では使用できて、C#では使用できない言語機能の一覧です。

コンパイラの機能
説明
名前付きのインデックス付きプロパティ

C# では、デフォルトのインデックス付きプロパティにのみアクセスできます。Oxygeneでは、名前を使用して、ほかのインデックス付きプロパティを定義して使用できます。

集合

集合は、同じ型の順序値のコレクションです。集合を使用すると、同じグループに属している値の格納やアクセスが簡単にできます。

並列処理のサポート

メソッドに async 指令を指定すると、そのメソッドは自動的に別のスレッドで実行されます。メソッドが値を返す場合、その値はフューチャになります。

コロン演算子

これはヌル値可能型のサポートに不可欠なものですが、意外にも、一般的なコーディングにも役に立つ機能です。基本的に、"." を使用してメンバにアクセスすると、メンバが nil の場合は NullReferenceException が返りますが、":" を使用すると、nil の場合は呼び出しがスキップされます(結果自体も nil なります)。次に例を示します。

// インターフェイスが実装されている場合にのみ Dispose を呼び出します。
IDisposable(SomeObject):Dispose;
// いずれかのレベルが nil の場合、コントロールの 3 番目の親にアクセスします。
x := Button:Parent:Parent:Parent;
インライン プロパティ アクセッサ

余分な setter/getter を使用することなく、クラス宣言内で簡単にプロパティを定義します。

property Foo: String; // 暗黙でローカル フィールドになります。
property Right: Int32 read Left+Width; // リーダー式をインラインで提供します。
クラス コントラクト
  1. クラスに対して "public invariants" を定義できます。これは、private ではないメソッドが終了するときには 常に 適用されて、クラスの内部構造が検証されます(同様に、"private invariants" を定義することもでき、private メソッドが終了するときに適用されます)。invariants は、クラスが有効な状態であるために、すべてが "true" になる必要のある論理式のリストです。
  2. メソッド本体の前に "require" セクションを追加し、後に "ensure" セクションを追加することで、事前条件と事後条件を定義できます。これらも、true かどうかを検査される論理ステートメントです。
クラス参照

"class of X" 型と仮想クラス メソッドを定義します(Delphi for Win32 と似ています)。

"implies" 演算子

主として、invariants または事前/事後条件に対して役に立ちます。基本的に、第 1 の部分が true の場合にのみ、第 2 の部分は true である "必要があります"。第 1 の部分が false の場合は、式全体が true になります。奇妙に感じるかもしれませんが、次のような場合を考えてみてください。

require
   assigned(Customer) implies Customer.CreditRatio > 5;

これは、次のようにも表すことができます。

require
   (NOT assigned(Customer)) OR (Customer.CreditRatio > 5);

比べてみると、前者の方が はるかに 分かり易いことがわかります。

"case type of"

特定のオブジェクトの TYPE(型) に応じて異なる case を実行する switch/case 文を記述します。次に例を示します。

case type MyControl of:
  Edit: // 何かを行います
  Button: // 何かを行います
end;
プロパティ通知

大量の定型コードが不要になります。"notify" キーワードを指令として("virtual" のように)プロパティに付加すると、プロパティ通知を実行するために必要なすべての基盤と複数のインターフェイスが、コンパイラによって生成されます(C# では、getter/setter を実装したり、クラスに複数のインターフェイスを追加したりする必要があります)。

強化されたヌル値可能型

C# とは異なり、Oxygeneコンパイラはヌル値可能型を完全にサポートします。ヌル値可能型のメンバを呼び出し、式の中で使用できます。ヌル値可能の式が広範にサポートされています。算術計算に寄与するいずれかの部分が "ヌル値可能" の場合は、式全体がヌル値可能になります。いずれかの部分がヌルの場合は、式全体がヌルになります。次に例を示します。

x: nullable Int32;
y: Int;
var a := x+y; // 結果はヌル値可能な Int32 です。
var b := 5*x; // x がヌルの場合は、b もヌルになります。
改良された 'for each' ループ
for each matching x: Button in Controls do    // ボタンに対してのみループを実行します。
// i を使用してカウントします。ジェネリック列挙型の場合は、
// x の型も "Controls" の型から自動的に推論されます。
for each x in Controls index i do    
'locked' 指令

locked 指令を使用すると、メソッド、イベント、およびプロパティを暗黙的にスレッド セーフとして宣言できます。

拡張コンストラクタ呼び出し

コンストラクタ呼び出しの一部としてプロパティを設定します。これは、ローカル参照に代入するのではない場合に特に便利です。次に例を示します。

Controls.Add(new Button(Width := 100; Height := 50));

これができないと、ボタン用に一時変数が必要になります。

これは、C# 3.0 で可能になりました。.

二重論理比較
if 0 <= x < Count then //...
反復のデリゲート

yield キーワードは、第 2 のシーケンスへのイテレータのデリゲートをサポートします。

空のメソッド

メソッドのインターフェイス宣言で 'empty' 指令を指定すると、空のメソッドの本体を定義する必要がありません。

例外フィルタ

型だけでなく、任意の条件に基づいても、例外を選択的に検出できます(VB.NET ではサポートされていますが、C# ではサポートされていません)。

イベントの発生

イベントの発生に対して可視性を指定できます。C# では、イベントを発生させることができるのは、そのイベントを定義しているクラスだけです(外部からは、ハンドラの追加/削除のみができます)。Oxygeneでは、次のように記述すると、下位オブジェクトでイベントを発生させることができます。

public
  event Foo:EventHandler protected raise;
 


Server Response from: ETNASC04