2009-07-24 33 views
5

Tôi có một lớp học có hàng tá tài sản đại diện cho các lĩnh vực tài chính khác nhau. Tôi có một lớp khác cần thực hiện một số phép tính trên từng trường đó một cách riêng biệt. Mã bên trong các phương pháp tính toán đó giống hệt nhau ngoại trừ trường mà nó tính toán.Làm thế nào tôi có thể chuyển thuộc tính của một lớp như một tham số của một phương thức?

Có cách nào để tôi có thể chuyển tên thuộc tính làm tham số và chỉ có một phương pháp thực hiện tất cả công việc thực hiện thay vì 12 phương pháp cho mỗi thuộc tính không? Ngoài ra, tôi chắc chắn điều này có thể được thực hiện thông qua sự phản ánh, nhưng tôi đã nhìn thấy trong mã khác nơi lambdas được sử dụng trong cùng một loại thời trang và đã tự hỏi nếu đây là một ứng cử viên nơi này có thể được sử dụng.

Theo yêu cầu, đây là một ví dụ:

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 
} 

Mục tiêu của tôi là chỉ cần thực hiện một phương pháp gọi là GetTotalAmountByDate() và vượt qua trong một ngày bắt đầu và ngày kết thúc và tên của tài sản (ReleasedFederalAmount hoặc ReleasedLocalAmount, v.v.) cần truy cập.

Tôi hy vọng điều này mô tả chính xác những gì tôi đang cố gắng hoàn thành.

+0

Nó sẽ được dễ dàng hơn để trả lời nếu bạn có thể chia sẻ một ví dụ về một hàm như vậy, và một cái nhìn thoáng qua về những đặc tính của lớp có thể trông như thế nào. –

+2

Tôi tò mò tại sao phương pháp tính toán của bạn không thể thực hiện, ví dụ, trường hợp của lớp trường tài chính và giá trị (nghĩa là giá trị của thuộc tính mà bạn muốn thực hiện phép tính) làm tham số. Bạn có thể đăng một số mã sơ khai để chiếu sáng câu hỏi của bạn không? –

+0

sử dụng cùng một loại trong chức năng defination của bạn, mà bạn đã sử dụng trong thuộc tính của lớp. –

Trả lời

5

Bạn không cần phải suy nghĩ nếu thuộc tính của bạn là tất cả các số và có thể được xử lý đồng nhất dưới dạng một loại - giả sử là decimal.

Something như thế này nên làm như lừa:

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

Bạn có thể sau đó cung cấp tên một cách thích hợp các phiên bản cho tất cả các trường hợp cụ thể của bạn:

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

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

// other versions .... 
+0

Đây chính xác là những gì tôi đang tìm kiếm, cảm ơn! –

0

Ngoài đề xuất dựa trên lamba tốt từ Jon Skeet, bạn có thể thử một cái gì đó như thế này. (Tất nhiên, nó có thể thay đổi cách một số mã của bạn hoạt động.)

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

Đây có lẽ là câu trả lời công nghệ thấp nhất, nhưng tại sao không sử dụng công tắc và hợp nhất nhiều "GetTotal ... Số tiền " chức năng?

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

Điều này có vẻ an toàn hơn, vì tất cả logic của bạn vẫn nằm trong tầm kiểm soát của bạn (không ai chuyển cho bạn chức năng thực thi).

này có thể được tiếp tục chia nhỏ nếu bạn cần phải thực sự làm những việc khác nhau với số tiền khác nhau:

Lấy phần chế biến và biến nó thành một chức năng:

 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; 
    } 
Các vấn đề liên quan