I have a class that has a dozen or so properties that represent various financial fields. I have another class that needs to perform some calculations on each of those fields separately. The code inside those calculation methods are identical except for the field that it does the calculation on.
Is there a way that I can pass a property name as a parameter and just have one method that does all of the performing work instead of the 12 methods for each property?
Also, I'm sure this can be accomplished via reflection, but I've seen in other code where lambdas are used in this same kind of fashion and was wondering if this is a candidate where this can be used.
As requested, here is an example:
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
}
My goal is to just make one method called GetTotalAmountByDate() and pass in a begin date, and end date and the name of the property (ReleasedFederalAmount or ReleasedLocalAmount, etc.) it needs to access.
I hope this depicts accurately what I'm trying to accomplish.
Parameters can be passed to a method in following three ways : Value Parameters. Reference Parameters. Output Parameters.
In C#, arguments can be passed to parameters either by value or by reference. Remember that C# types can be either reference types ( class ) or value types ( struct ): Pass by value means passing a copy of the variable to the method. Pass by reference means passing access to the variable to the method.
Note: Parameters refers to the list of variables in a method declaration. Arguments are the actual values that are passed in when the method is invoked. When you invoke a method, the arguments used must match the declaration's parameters in type and order.
The ref keyword in C# is used for passing or returning references of values to or from Methods. Basically, it means that any change made to a value that is passed by reference will reflect this change since you are modifying the value at the address and not just the value.
You don't need reflection if your properties are all numeric and can be homogeneously treated as a single type - let's say a decimal
.
Something like this should do the trick:
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;
}
You can then provide appropriately named versions for all of your specific cases:
public decimal GetTotalReleasedFederalAmountByDate()
{
return ComputeFinancialSum( BeginDate, EndDate,
(x) => x.ReleasedFederalAmount );
}
public decimal GetTotalReleasedNonFederalAmountByDate()
{
return ComputeFinancialSum( BeginDate, EndDate,
(x) => x.ReleasedNonFederalAmount );
}
// other versions ....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With