2009-07-24 32 views
5

Çeşitli finansal alanları temsil eden bir düzine kadar özelliği olan bir sınıfım var. Bu alanların her birinde ayrı ayrı hesaplamalar yapması gereken başka bir dersim var. Bu hesaplama yöntemlerinin içindeki kod, hesaplamayı yaptığı alan haricinde aynıdır.Bir sınıfın bir özelliğini bir yöntemin parametresi olarak nasıl geçirebilirim?

Bir özellik adını parametre olarak iletebilmem için bir yol var mı ve yalnızca her bir özellik için 12 yöntem yerine tüm gerçekleştirme işini yapan bir yöntem var mı?

Ayrıca, bunun yansıma yoluyla gerçekleştirilebileceğine eminim, ama lambdaların da aynı şekilde kullanıldığı başka bir kodda gördüm ve bunun kullanılabileceği bir aday olup olmadığını merak ediyorum.

İstendiği gibi

, burada bir örnek:

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 
} 

Amacım sadece GetTotalAmountByDate (denilen bir yöntem olun) ve bir başlamak tarihe geçmek olduğunu ve bitiş tarihi ve mal adı (ReleasedFederalAmount veya ReleasedLocalAmount, vb.) Erişmesi gerekiyor.

Umarım bu, neyi başarmaya çalıştığımı gösterir.

+0

Size bir paylaşabilirsiniz cevap vermek daha kolay olacaktır Böyle bir fonksiyon örneği ve sınıf özelliklerinin neye benzeyebileceğine dair bir bakış. –

+2

Hesaplama yönteminizin neden finansal alan sınıfının örneğini ve parametre olarak bir değeri (yani, hesaplamayı gerçekleştirmek istediğiniz mülkün değeri) almadığını merak ediyorum. Sorunuzu aydınlatmak için bazı kodlama kodu gönderebilir misiniz? –

+0

, sınıfın özelliklerinde kullandığınız işlev tanımlamanızda aynı türü kullanır. –

cevap

5

Sen yansıma gerekmez Eğer özelliklerin hepsi sayısalsa ve tek tip olarak homojen olarak işlenebilirse - decimal diyelim. Böyle

şey hile yapmak gerekir:

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; 
} 

yapabilirsiniz o zaman özel durumların tümü için uygun adında versiyonlarını sağlar:

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

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

// other versions .... 
+0

Bu tam olarak aradığım şey, teşekkürler! –

0

Jon Skeet'in iyi lamba tabanlı önerisinden ayrı olarak, böyle bir şey deneyebilirsiniz.

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

Bu burada muhtemelen en düşük teknolojili cevaptır (Tabii ki, bu. Kodunuzun bazı çalışma şeklini değiştirebilecek), ama neden sadece bir anahtarı kullanın ve birden birleştirme "GetTotal ... Tutar "işlevler? tüm mantık (kimse çalıştırmak için size işlevleri geçiyor) sizin kontrolünüz altında kaldığından

// 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; 
    } 

Bu, daha güvenli görünüyor.

işleme parçasını alın ve bir işlevi çevirmek:

farklı miktarlarda farklı şeyler aslında yapmak gerekiyorsa bu daha da bölünebilir

 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; 
    } 
İlgili konular