1

Person というタイプのオブジェクトのリストがあり、Person レコードを Excel シートにエクスポートしたいと考えています (VB.NET 用の独自の Excel コンポーネントを使用しています)。チェックボックスのあるフォームを使用して、ユーザーはどの Person プロパティをエクスポートするかを指定できます。

各チェックボックス (プロパティに対応) がチェックされているかどうかをチェックする巨大な if-then-else ツリーの代わりに、Person の各プロパティに対してブール値 (チェック/チェックなし) を保持するデータ構造を持っています。文字列としてのプロパティの名前。次に、次のように 2 つの for ループを使用します。

For Each p As Person In Persons
    ...
    For Each item As ExportColumnData In ExportColumnTable
        ...
        If item.Checked Then
            ...
            Dim o As Object = CallByName(p, item.PropertyName, CallType.Get, Nothing)
            SaveValueToExcelSheet(o)
            ...
        End If
        ...
    Next
    ...
Next

ただし、PropertyName を文字列として提供する CallByName を使用しているため、これはタイプ セーフではありません。同じことを達成できる、よりエレガントでタイプセーフな方法はありますか? これらの Person オブジェクトのプロパティを参照するには、何らかの方法 (文字列以外) が必要です。

4

3 に答える 3

0

この関数はリフレクションを使用して、文字列名でプロパティ ゲッターを見つけて実行します。そのため、これらの名前のプロパティが実際に型CallByNameに存在することを確認するコンパイル時のチェックが行われないという意味で安全ではないことは間違いありません。Person.

残念ながら、大きなIf/Elseブロックなどを除いて、コンパイル時の型チェックを可能にする「安全な」方法はありません。コンパイル時にそれをチェックしたい場合は、コードで直接名前でプロパティを呼び出す必要があります。それを行う場合は、何らかの大きな条件付きブロックにある必要があります。

醜さの場所を最小化または移動するためにできることがあります。たとえば、すべてのプロパティの列挙を作成し、大きなブロックを使用して列挙項目に指定されたプロパティ値を返すPersonメソッドをクラスに追加できます。これにより、ロジックが再利用可能になりますが、それほど醜いわけではありません。それだけでなく、そのようにすることで、コンパイラではなくコードに型チェックの責任を負わせることになります。PersonSelect Case

または、たとえば、各コントロールのタグを、オブジェクトを受け取り、指定されたオブジェクトからそのオプションの正しいプロパティ値を返すCheckBoxデリゲートに設定することもできます。次に、ループ内でタグ内のデリゲートを呼び出すだけで、値を取得できます。たとえば、次のようなデリゲートがあるとします。PersonPerson

Private Delegate Function GetPersonProperty(x As Person) As Object

Tag次に、次のようにCheckBoxコントロールを設定できます。

chkFullName.Tag = New GetPersonProperty(Function(x As Person) x.FullName)
chkAge.Tag = New GetPersonProperty(Function(x As Person) x.Age)

次に、ループ内でデリゲートを呼び出して、次のTagように値を取得できます。

Dim myDelegate As GetPersonProperty = CType(item.Tag, GetPersonProperty)
Dim value As Object = myDelegate.Invoke(p)

しかし、このような単純なタスクに対しては、かなり複雑です。

最後に、コンパイル時の型チェックが本当に重要である場合、私は弾丸を噛んで大きな条件付きブロックを作成します。それほど重要でない場合は、リフレクションに固執し、適切な例外処理をコードに入れます。

于 2013-07-31T12:47:47.337 に答える
0

ExportColumnDataの内容が正しい限り、ソリューションはまったく問題ありません。これらが実行時に動的に計算される場合は問題ありません。

それ以外の場合、または代わりに、次のことを行うことができます: を使用Type.GetPropertiesしてオブジェクトのリストを取得しPropertyInfoます。次に、単なる文字列の代わりにこれらを使用して、ループでプロパティ値を抽出できます。

Dim o As Object = item.PropertyInfo.GetValue(p, Nothing)
于 2013-07-31T12:44:53.693 に答える