- PR -

C#→VB2005 での匿名メソッドについて

1
投稿者投稿内容
あー
会議室デビュー日: 2008/05/09
投稿数: 8
投稿日時: 2009-03-27 11:00
現在「実践!ソフトウェアアーキテクチャ」(尾島良司氏 著)を参考にしながら、
業務アプリを VB2005 にて開発しているものです。

最初はアーキテクチャを参考にしようと購入しました。
サンプルもあり C# ですが、特にクラスライブラリが使えそうだったので
VB へコンバートして使えるようにしようと試みました。
しかし標記の匿名メソッド( delegate ) を多用しており、VB にうまく変換できません。。

Transaction, Trace, Form での EventLog などの処理をやる際に、

コード:

RXForBusiness.TraceInAndOut(
delegate
{
// トランザクション処理を開始
RXForBusiness.ExecuteTansaction(
delegate
{
// エラーチェック
RXForBusiness.CallValidators(dataSet.Category);

// エラーが発見されたら、更新せずリターン
if(dataSet.HasErrors)
{
return;
}

// データベースを更新
r = RXForBusiness.CallUpdateTableAdapters(dataSet.Category);
},
dataSet);
});



のように使っており、RXForBusiness のメソッドから処理をつけて、
Trace の開始・終了や TransactionScope で、引数でつけた処理を挟んでいます。

VB で変換するには厳しいでしょうか?
もし上記本を参考にした方はアドバイス下さい。宜しくお願いします。

[ メッセージ編集済み 編集者: あー 編集日時 2009-03-27 11:07 ]

[ メッセージ編集済み 編集者: あー 編集日時 2009-03-27 11:08 ]
デューン
大ベテラン
会議室デビュー日: 2004/04/21
投稿数: 174
お住まい・勤務地: Tokyo
投稿日時: 2009-03-27 11:47
引用:

あーさんの書き込み (2009-03-27 11:00) より:

VB で変換するには厳しいでしょうか?



本ももってない上にどっちかといえばC#の人なので自信はありませんが、


delegateというかRXForBusiness.TraceInAndOut()
はActionを引数にとっていると思います

その場合、単純なケースでは以下のような書き方で変換が可能です。
コード:

Public Class Hoge

Dim dataSet As DataSet = Nothing

Public Sub mi()

RxHoge.TraceInAndOut(New [Action](AddressOf Me.DelegateHoge))

End Sub

Public Sub DelegateHoge()

End Sub

End Class


Public Class RxHoge

Public Shared Sub TraceInAndOut(ByVal dg As Action)
dg.Invoke()
End Sub

End Class



ただ、今回のケースではdataSetメンバへの参照が問題となりますので、
問題があればRxなんとかともどもAction(Of DataSet)に変更することを検討してください。
(この場合DelegateHoge内でdataSetメンバにアクセスするとどうなるかは確認してません)


[ メッセージ編集済み 編集者: デューン 編集日時 2009-03-27 11:49 ]
よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2009-03-27 11:52
VB2005 だと匿名メソッドはサポートされていませんので、ちゃんとメソッドを用意する必要があります。

コード:
Public Sub Hoge()
  RXForBusiness.TraceInAndOut(AddressOf Fuga)
End Sub

Private Sub Fuga()
  ' トランザクション処理を開始
  RXForBusiness.ExecuteTansaction(AddressOf Piyo, dataSet)
End Sub

Private Sub Piyo()
  ' エラーチェック
  RXForBusiness.CallValidators(dataSet.Category)
  
  ' エラーが発見されたら、更新せずリターン
  If (dataSet.HasErrors) Then
    return
  End If

  ' データベースを更新
  r = RXForBusiness.CallUpdateTableAdapters(dataSet.Category)
End Sub



結構面倒なので、簡単になるよう工夫すると良いと思います。
工夫の仕方は色々あると思いますが、例えば RXForBusiness.cs に次のようなメソッドを追加しておけば、

コード:
public static void ExecuteTransactionWithTraceInAndOut(Procedure transactionProcedure, DataSet consistentFlagDataSet)
{
  ExecuteTransactionWithTraceInAndOut(transactionProcedure, consistentFlagDataSet, TransactionScopeOption.Required);
}

public static void ExecuteTransactionWithTraceInAndOut(Procedure transactionProcedure, DataSet consistentFlagDataSet, TransactionScopeOption transactionScopeOption)
{
  TraceInAndOut(
    delegate()
    {
      ExecuteTansaction(transactionProcedure, consistentFlagDataSet, transactionScopeOption);
    });
}



次のようにメソッドを一つ減らすことができます。

コード:
Public Sub Hoge()
  RXForBusiness.ExecuteTransactionWithTraceInAndOut(AddressOf Piyo, dataSet)
End Sub

Private Sub Piyo()
  ' エラーチェック
  RXForBusiness.CallValidators(dataSet.Category)
  
  ' エラーが発見されたら、更新せずリターン
  If (dataSet.HasErrors) Then
    return
  End If

  ' データベースを更新
  r = RXForBusiness.CallUpdateTableAdapters(dataSet.Category)
End Sub




_________________
C#と諸々
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2009-03-27 13:46
昔本屋でちょっと見てみただけなので詳細は覚えてませんが、
あの本では、匿名メソッドを利用することで、Before Afterパターン的な処理などを
簡潔に記述する、という趣旨だったはずです。

で、当然匿名メソッドが使えることが大前提で、使えないVBでは簡潔どころか複雑化するだけでほとんど意味がありません。

使おうと思えばメソッドを切り出したりして使えますが、あえてやる意味はないでしょう。
よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2009-03-27 16:31
引用:
なちゃさんの書き込み (2009-03-27 13:46) より:

昔本屋でちょっと見てみただけなので詳細は覚えてませんが、
あの本では、匿名メソッドを利用することで、Before Afterパターン的な処理などを
簡潔に記述する、という趣旨だったはずです。

で、当然匿名メソッドが使えることが大前提で、使えないVBでは簡潔どころか複雑化するだけでほとんど意味がありません。

使おうと思えばメソッドを切り出したりして使えますが、あえてやる意味はないでしょう。



手元にあるので見てみましたが、一々継承などを使わずとも制御の逆転を実現できるよ、という視点で書かれてました。
もちろん、匿名メソッドが使える場合に比べて遥かに見劣りしますが、
読みやすさ以外のメリットまでは損なわれないので、
決して意味がないわけではないかなと思います。
# まぁ、読みにくさによるデメリットが大きいんじゃ、割に合わないかもしれませんが
_________________
C#と諸々
1

スキルアップ/キャリアアップ(JOB@IT)