An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
Two things:
- Your
overrideofAggregateinCCAggregatedPerformancehas differently named type arguments than those defined in the base classAggregatedPerformance. Not a technical issue, but denotes an assumption that the type passed can't be another derived type ofLoanPerformancewhen it is possible with the constraints applied in the base class. - The
overrideofAggregatealso had a name collision between the first type argument (CreditCardPerformance) and the classCreditCardPerformance. Renaming this type argument resolves the issue.
Updated:
public class LoanPerformance {
public decimal Principal { get; set; }
}
public class AggregatedPerformance {
public int LoanId { get; set; }
public decimal Principal { get; set; }
public virtual void Aggregate<TLoanPerformance, TAggregated>(IEnumerable<TLoanPerformance> loanPerformances, Action<TLoanPerformance> accumulator)
where TLoanPerformance : LoanPerformance
where TAggregated : AggregatedPerformance, new() {
foreach (TLoanPerformance loanPerformance in loanPerformances) {
this.Principal += loanPerformance.Principal;
accumulator(loanPerformance);
}
}
public void Aggregate<TLoanPerformance, TAggregated>(IEnumerable<TLoanPerformance> loanPerformances)
where TLoanPerformance : LoanPerformance
where TAggregated : AggregatedPerformance, new() {
Aggregate<TLoanPerformance, TAggregated>(loanPerformances, _ => { });
}
}
public class CreditCardPerformance : LoanPerformance {
public decimal CreditLimit { get; set; }
}
public class CCAggregatedPerformance : AggregatedPerformance {
public decimal CreditLimit { get; set; }
public override void Aggregate<TLoanPerformance, TAggregated>(IEnumerable<TLoanPerformance> loanPerformances, Action<TLoanPerformance> accumulator) {
base.Aggregate<TLoanPerformance, CCAggregatedPerformance>(loanPerformances,
(_perf) => {
var creditCardPerf = _perf as CreditCardPerformance;
if (creditCardPerf != null) {
this.CreditLimit += creditCardPerf.CreditLimit;
}
});
}
}