UML から C# への変換の再実行時の考慮事項

UML から C# への変換により、@generated タグが生成された特定の要素に追加されます。 変換の再実行時には、変換により、@generated タグつきの要素は上書きされます。 生成されたコードに対する変更を保護するには、コードに書きこまれた @generated タグを除去する必要があります。 モデル化できない C# 要素を示す場合は、変換出力のユーザー定義のセクションにコードを追加します。

変換により生成される要素

UML から C# への変換により、@generated タグが以下の要素に追加されます。

生成されたコードの保護

UML から C# への変換を再実行する場合、 デフォルトでは、変換によって生成されるメソッド本文も、ユーザーが作成したメソッド本文もその変換では上書きされません。 変換では、@generated タグを削除したかどうかにかかわらず、メソッド本文は常に保持されます。

以下の要素から @generated タグが削除されていない場合は、それが最上位にあってもネストされている場合でも、変換により上書きされます。
  • クラス
  • 構造体
  • 列挙型
  • 委譲
  • フィールド
  • メソッド
  • プロパティー

変換では常にメソッド本文は保持されますが、 メソッドに対する構造上の変更点を保持するには、メソッドから @generated タグを削除する必要があります。 例えば、メソッド・シグニチャーを変更した場合や、コンストラクターにイニシャライザーを追加した場合、メソッドに例外を追加した場合、ソース・コードにコメントを追加した場合などは、そのメソッドから @generated タグを削除する必要があります。

@generated タグを削除しないと、@generated タグが適用される要素が変換により上書きされます。 変換では、以下の要素も上書きされます。
  • キーワード
  • クラスのメンバー
  • パラメーター
注: ソースの UML モデルにメソッドを追加するには、後方変換を実行します。

新規コードの保護

生成済みまたは非生成済みのソース成果物に入力するコードは、 UML でコードが認識されているかどうかにかかわらず、 続く前方変換および後方変換での上書きから保護することができます。 例えば、C# プリプロセッサー・ディレクティブは認識されませんが、 保持されます。 次の要素タイプやユーザー・コードの領域は保護されます。
  • 属性およびネスト・タイプ
  • 各ソース・ファイルでのユーザー定義セクション
  • 生成済みのタイプおよびタイプ・メンバーの周りにある、 プリ・ユーザー・コードとポスト・ユーザー・コードのセクション
変換では、C# コードに追加した属性、ネスト・クラス、構造体、および列挙は、それらの要素に誤って @generated タグが追加されない限り、上書きされません。
注: ソース UML モデルに属性、ネスト・クラス、構造体、または列挙を追加する場合は、後方変換を実行してください。

また、変換で作成されるユーザー定義セクションにコードを追加することもできます。 変換では、ユーザー定義セクション内に指定されたコードは上書きも削除もされません。

変換では、コード・ファイルにユーザー定義のセクションを生成します。 変換により、1 つのユーザー定義セクションがそれぞれのファイルの先頭に追加されます。 このセクションを使用して、using ステートメントを指定できます。
注: ユーザー定義セクションではタイプを入力しません。 このセクションは、using ステートメントの宣言に対してのみ使用されます。
ユーザー・コードを保持する別の方法は、プリ・ユーザー・コードおよび ポスト・ユーザー・コードのセクションを活用することです。 これらのセクションは次の生成済みの C# 要素の前後に存在します。
  • タイプ・メンバー - フィールド、メソッド、委譲、イベントを含みます
  • コンポジット型宣言 - クラス、構成、インターフェースを含みます
  • 委譲
  • 列挙型
  • 名前空間

上記の要素の直後に入力するユーザー・コードは、 間にブランク行を挿入しないかぎり、変換によって直前の要素のポスト・ユーザー・コード として解釈されます。ブランク行の後に入力するすべてのユーザー・コードは、 変換によって、続く要素のプリ・ユーザー・コードとして解釈されます。

@generated タグおよびユーザー定義のプリ・ユーザー・コードおよびポスト・ユーザー・コードのセクションによって柔軟性が提供されますが、発生する可能性のある問題を回避するには、生成されたコードにではなく、ソース UML モデルに対して構造上の変更を行う必要があります。 また、後方変換を実行し、ソース UML モデルに対して新規のメソッドまたは属性を追加することもできます。

プリ・ユーザー・コードおよびポスト・ユーザー・コードの実装の例

標準の要素、名前空間、コメントについてのプリ・ユーザー・コードおよびポスト・ユーザー・コードの実装には、 いくつかのバリエーションが存在します。

標準の要素

以下のコード・スニペットを参照してください。

#if DEBUG
 // @generated
 // @C#_transform [
 // _URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_KBkvkMtZEd2IB4RiswwPkg
 // ]
 public void Operation1()
 {
  //TODO: 自動生成されたメソッド・スタブ
  throw new System.NotImplementedException();
 }
#endif

 // @generated
 // @C#_transform [
 // _URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_UxwLEc2-Ed2itJx87rzLyg
 // ]
 public void Operation2()
 {
  //TODO: 自動生成されたメソッド・スタブ
        throw new System.NotImplementedException();
 }

上記の例では、#endif ディレクティブは Operation1 要素のポスト・ユーザー・コードのセクションです。2 つの要素 の間にブランク行がない場合、最初の要素の終わりから @generated@C#_transform [、または次の要素の初めまでのすべてのコードは、 最初の要素のポスト・ユーザー・コードとみなされます。スペース挿入の規則には例外があります。 要素の後にスペースがあり、続いてユーザー・コードがあってその他の追加要素がない場合、 ユーザー・コードは次の例で示されるように、前の要素のポスト・ユーザー・コードとして 添付されます。

public class Class1
{

         // @generated
        // @C#_transform [
 // _URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_KBkvkMtZEd2IB4RiswwPkg
        // ]
        public void Operation1()
       {
           //TODO: 自動生成されたメソッド・スタブ
          throw new System.NotImplementedException();
       }
 
      // @generated
      // @C#_transform [
      // _URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_UxwLEc2-Ed2itJx87rzLyg
      // ]
      public void Operation2()
      {
          //TODO: 自動生成されたメソッド・スタブ
         throw new System.NotImplementedException();
       }
 
#endif
}

名前空間と #define ステートメント

名前空間にある 要素は分割可能で、コンパイル・ユニットにある同じ名前空間の他の要素とマージすることができます。 一般原則として、名前空間にあるコンポジット・タイプの宣言、列挙、委譲が、 例えばマッピング・モデルを使用して他のコンパイル・ユニットに移動された場合、 要素は、ソース・ユニットのエンクロージング名前空間のユーザー・コードをターゲット・ユニットの名前空間に移し、 ターゲットの既存のユーザー・コードに付け加えます。

以下の Class1.cs のサンプル・コードを参照してください。

public class Class1
{
}

#region com-Class1
namespace com
{
	public class Class3
{
}


public class Class4
{
}
}
#endregion

Class2.cs:
public class Class2
{
}

#region com-Class2
namespace com
{
	public class Class5
{
}
}
#endregion

com.Class4 が Class2.cs に移動されるようにマッピング・モデルを変更した場合、 前方変換をした後の結果コードは次の例のように生成されます。

Class1.cs

public class Class1
{
}

#region com-Class1
namespace com
{
	public class Class3
{
}

}
#endregion

Class2.cs

public class Class2
{
}

#region com-Class2
#region com-Class1
namespace com
{

public class Class4
{
}


	public class Class5
{
}
}
#endregion
#endregion

プリ・ユーザー・コードとポスト・ユーザー・コードの要素 #region com-Class1#endregion は、 変換によって既存のユーザー・コードに追加されます。プリ・ユーザー・コードは後ろに付加されますが、 ポスト・ユーザー・コードは前に付加されます。

同様に、 コンポジットの型宣言または名前空間がマッピング・モデルを通して 1 つのコンパイル・ユニットから別のコンパイル・ユニットに移動された場合、ソース・ユニットの #define#undef ステートメントはターゲット・ユニットに付加されます。

コメント

プリプロセッサー・ディレクティブの上にある コメントは関連があるとみなされ、ユーザー・コードとして保持されます。 コメントとプリプロセッサー・ディレクティブの順序付けは維持されます。 以下のコード・スニペットを参照してください。

// @generated
// @C#_transform [
//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_0o-fIOhIEd2SdrLLRilfrw
//	]
public class Class1
{

	#region c
	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_S4TRgOkaEd2owca4Ri32gw
	//	]
	public void Operation2()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}
//region ends
#endregion



    
//comment for a
    #region a
    //comment for b
    #region b

	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_vZgVUOhjEd2vc-H9Qq-k_Q
	//	]
	public void Operation1()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}
//end b
    #endregion
    //end a
    #endregion

}

Operation2() の後から #endregion ディレクティブまでのコードは、 メソッドのポスト・ユーザー・コードとして割り当てられます。ブランク行が現れる位置から 最後のプリプロセッサー・ディレクティブまでの間のすべてに対して、 Operation1() のプリ・ユーザー・コードが割り当てられます。これにはコメントも含まれます。 プリ・ユーザー・コードには //region ends のコメントが、ポスト・ユーザー・コードには //comment for a//comment for b のコメントが付けられます。これにより、 ディレクティブに関連のあるすべてのコメントが保持されます。

変換とモデル・プロパティー に関連のある UML 文書はユーザー・コードとしては格納されません。 UML 文書はモデルの中に格納されます。 プリプロセッサー・ディレクティブが非モデル要素として含まれている場合、 変換を再適用すると、すべての非モデル要素で文書は保持されますが、モデル要素の文書はモデルの「文書」タブから取られます。

コード保持機能の制限事項

プリ・ユーザー・コード・セクションとポスト・ユーザー・コード・セクションにコードを追加した後、UML から C# への変換を再実行すると、変換により、ソース・コード中の特定の要素が再配列されます。

例えば、以下のコード・スニペットは UML から C# への変換で生成されたものですが、ソフトウェア開発者は、Operation2()Operation1() の間に attribute1 という属性を追加しました。

// @generated
// @C#_transform [
//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_GXpy8Nr5Ed2zKbxEG_6cmQ
//	]
public class Class2
{

	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_tnNPwNsGEd2zKbxEG_6cmQ
	//	]
	public void Operation2()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}

#if DEBUG
    // @generated
    // @C#_transform [
    //	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_HEXH8Nr5Ed2zKbxEG_6cmQ
    //	]
    private Object attribute1;


	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_HYxRsNr5Ed2zKbxEG_6cmQ
	//	]
	public void Operation1()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}
#endif

}

開発者が UML から C# への変換を再実行すると、attribute 1 という属性、およびそれに添付されたプリ・ユーザー・コードがコードの先頭に移動します。 変更後のコードは、以下の例のようになります。

// @generated
// @C#_transform [
//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_GXpy8Nr5Ed2zKbxEG_6cmQ
//	]
public class Class2
{


#if DEBUG
	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_HEXH8Nr5Ed2zKbxEG_6cmQ
	//	]
	private Object attribute1;



	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_tnNPwNsGEd2zKbxEG_6cmQ
	//	]
	public void Operation2()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}



	// @generated
	// @C#_transform [
	//	_URI=platform:/resource/GraphicsLibraryProject/GraphicsModel.emx#_HYxRsNr5Ed2zKbxEG_6cmQ
	//	]
	public void Operation1()
	{
		// TODO: 自動生成されたメソッド・スタブ
		throw new System.NotImplementedException();
	}
#endif

}

要素の順序が変わると、上記の例の #if ループなどのように、プリプロセッサーの処理結果に変更が生じ、そのためにコンパイル・エラーになることがあります。 手動で再配列して要素の順序が変わった場合、コード保持機能の動作は予測不能であるという点に開発者は十分注意する必要があります。


フィードバック