2009-07-24 17 views
5

私はさまざまな金融分野を表すダースまたはそれ以上のプロパティを持つクラスを持っています。私は、別々のフィールドのそれぞれでいくつかの計算を実行する必要がある別のクラスを持っています。これらの計算メソッド内のコードは、計算を行うフィールドを除いて同じです。クラスのプロパティをメソッドのパラメータとして渡すにはどうすればよいですか?

私はパラメータとしてプロパティ名を渡すことができ、それぞれのプロパティの12のメソッドではなく、すべての実行作業を行うメソッドが1つしかありませんか?

また、これは反射を介して達成できると確信していますが、ラムダがこの同じ種類のファッションで使用され、これが使用できる候補であるかどうか疑問に思っていた他のコードで見ました。要求され、ここでの例であるとして

public class FinancialInfo 
{ 
    public virtual DateTime AuditDate { get; set; } 
    public virtual decimal ReleasedFederalAmount { get; set; } 
    public virtual decimal ReleasedNonFederalAmount { get; set; } 
    public virtual decimal ReleasedStateAmount { get; set; } 
    public virtual decimal ReleasedLocalAmount { get; set; } 
    public virtual decimal ReleasedPrivateAmount { get; set; } 
    // more fields like this 
} 

public class FinancialLedger() 
{ 
    public virtual DateTime? BeginDate { get; set; } 
    public virtual DateTime? EndDate { get; set; } 
    public virtual IList<FinancialInfo> Financials { get; set; } //not actual implementation, but you get the idea 
    public decimal GetTotalReleasedFederalAmountByDate() 
    { 
     if (BeginDate == null && EndDate == null) 
      return 0; 
     decimal total = 0; 
     foreach (var fi in Financials) 
     { 
      if (someCondition) 
       if (someSubCondition) 
        total += fi.ReleasedFederalAmount; 
      else if (someOtherCondition) 
       if (someOtherSubCondition) 
        total += fi.ReleasedFederalAmount; 
      else if (anotherCondigion) 
       total += fi.ReleasedFederalAmount; 
     } 
     return total; 
    } 
    public decimal GetTotalReleasedNonFederalAmountByDate() 
    { 
     // same logic as above method, 
     // but it accesses fi.ReleasedNonFederalAmount; 
    } 
    // More methods the same as the previous, just accessing different 
    // members of FinancialInfo 
} 

私の目標はただGetTotalAmountByDate(と呼ばれる一つの方法を)作り、開始日に渡すことで、終了日およびプロパティの名前(ReleasedFederalAmountかReleasedLocalAmountなど)にアクセスする必要があります。

これは私が達成しようとしていることを正確に表してくれることを願っています。

+0

を答えるために容易になります。このような

何かがトリックを行う必要がありますそのような関数の例、クラスプロパティの外観を垣間見ることができます。 –

+2

私は、あなたの計算方法が金融分野のクラスのインスタンスと、(計算を実行するプロパティの値である)値をパラメータとして取ることができないのはなぜか不思議です。あなたの質問を照らすためにいくつかのスタブコードを投稿できますか? –

+0

は、クラスのプロパティで使用した関数の定義と同じ型を使用します。 –

答えて

5

あなたは反射を必要としませんあなたのプロパティがすべて数値であり、均等に単一の型として扱うことができる場合 - decimalとしましょう。あなたは、あなたの具体的な例すべてのための適切な名前のバージョンを提供することができます

protected decimal ComputeFinancialSum(DateTime? beginDate, DateTime? endDate, 
             Func<FinancialInfo,decimal> propertyToSum) 
{ 
    if (beginDate == null && endDate == null) 
     return 0; 
    decimal total = 0; 
    foreach (var fi in Financials) 
    { 
     if (someCondition) 
      if (someSubCondition) 
       total += propertyToSum(fi); 
     else if (someOtherCondition) 
      if (someOtherSubCondition) 
       total += propertyToSum(fi); 
     else if (anotherCondigion) 
      total += propertyToSum(fi); 
    } 
    return total; 
} 

:あなたが共有できるかどう

public decimal GetTotalReleasedFederalAmountByDate() 
{ 
    return ComputeFinancialSum(BeginDate, EndDate, 
           (x) => x.ReleasedFederalAmount); 
} 

public decimal GetTotalReleasedNonFederalAmountByDate() 
{ 
    return ComputeFinancialSum(BeginDate, EndDate, 
           (x) => x.ReleasedNonFederalAmount); 
} 

// other versions .... 
+0

これは私が探していたものです。ありがとう! –

0

Jon Skeetの良いlambaベースの提案は別として、このようなものを試すことができます。 (もちろん、それはあなたのコードの一部が動作する方法を変更することができます。)

public class ValueHolder 
{ 
    object Value; 
} 

public class Main 
{ 
    private ValueHolder value1 = new ValueHolder(); 
    private ValueHolder value2 = new ValueHolder(); 

    public Value1 { get { return value1.Value; } set { value1.Value = value; } } 
    public Value2 { get { return value2.Value; } set { value2.Value = value; } } 

    public ValueHolder CalculateOne(ValueHolder holder ...) 
    { 
    // Whatever you need to calculate. 
    } 

    public CalculateBoth() 
    { 
    var answer1 = CalculateOne(value1); 
    var answer2 = CalculateOne(value2); 
    ... 
    } 
} 
0

これはおそらく、ここで最低のハイテク答えですが、なぜ単にスイッチを使用し、複数のマージない「GetTotal ...金額" 機能?

// define some enum for your callers to use 
public enum AmountTypeEnum { 
    ReleasedFederal = 1 
, ReleasedLocal = 2 
} 

public decimal GetTotalAmountByDate(AmountTypeEnum type) 
    { 
     if (BeginDate == null && EndDate == null) 
      return 0; 
     decimal total = 0; 
     foreach (var fi in Financials) 
     { 
      // declare a variable that will hold the amount: 
      decimal amount = 0; 

      // here's the switch: 
      switch(type) { 
       case AmountTypeEnum.ReleasedFederal: 
        amount = fi.ReleasedFederalAmount; break; 
       case AmountTypeEnum.ReleasedLocal: 
        amount = fi.ReleasedLocalAmount; break; 
       default: break; 
      } 

      // continue with your processing: 
      if (someCondition) 
       if (someSubCondition) 
        total += amount; 
      else if (someOtherCondition) 
       if (someOtherSubCondition) 
        total += amount; 
      else if (anotherCondigion) 
       total += amount; 
     } 
     return total; 
    } 

ロジックはすべてあなたのコントロール下にあります(実行する関数を誰にも渡していないので)。

処理部を取り、機能にそれを回す:

あなたは異なる量の異なるものを実際に行う必要がある場合、これはさらに分解することができ

 private decimal ProcessNormal(decimal amount) { 
      decimal total = 0; 

      // continue with your processing: 
      if (someCondition) 
       if (someSubCondition) 
        total += amount; 
      else if (someOtherCondition) 
       if (someOtherSubCondition) 
        total += amount; 
      else if (anotherCondition) 
       total += amount; 
      return total; 
    } 

public decimal GetTotalAmountByDate(AmountTypeEnum type) 
    { 
     if (BeginDate == null && EndDate == null) 
      return 0; 
     decimal total = 0; 
     foreach (var fi in Financials) 
     { 
      // declare a variable that will hold the amount: 
      decimal amount = 0; 

      // here's the switch: 
      switch(type) { 
       case AmountTypeEnum.ReleasedFederal: 
        amount = fi.ReleasedFederalAmount; 
        total = ProcessNormal(amount); 
        break; 
       case AmountTypeEnum.ReleasedLocal: 
        amount = fi.ReleasedLocalAmount; 
        total = ProcessNormal(amount); 
        break; 
       case AmountTypeEnum.NonReleasedOtherAmount: 
        amount = fi.NonReleasedOtherAmount; 
        total = ProcessSlightlyDifferently(amount); // for argument's sake 
        break; 
       default: break; 
      } 
     } 
     return total; 
    } 
関連する問題