I have IPrice interface:
public interface IPrice
{
decimal TaxPercent { get; set; }
decimal TotalDebt { get; set; }
decimal Discount { get; set; }
DiscountTypeEnum DiscountType { get; set; }
decimal Commission { get; set; }
DiscountTypeEnum CommissionType { get; set; }
}
I have interface IExtendPrice and its default implementation:
public interface IExtendPrice
{
decimal TotalDebtWithoutTax { get; }
decimal TaxSum { get; }
decimal DiscountSum { get; }
decimal CommissionSum { get; }
decimal DebitPrice { get; }
}
public class ExtendPrice : IExtendPrice
{
private IPrice m_Price = null;
public ExtendPrice(IPrice price)
{
m_Price = price;
}
public decimal TotalDebtWithoutTax { get { return (m_Price.TotalDebt / (1 + (m_Price.TaxPercent / 100))); } }
public decimal TaxSum { get { return m_Price.TotalDebt - TotalDebtWithoutTax; } }
public decimal DiscountSum
{
get
{
decimal discount = m_Price.Discount;
if (m_Price.DiscountType == DiscountTypeEnum.PERCENTS)
{
discount = discount * NetoPrice / 100;
}
return discount;
}
}
public decimal CommissionSum
{
get
{
decimal commission = m_Price.Commission;
if (m_Price.CommissionType == DiscountTypeEnum.PERCENTS)
{
commission = commission * NetoPrice / 100;
}
return commission;
}
}
public decimal NetoPrice { get { return CalculateNetoPrice(); } }
private decimal CalculateNetoPrice()
{
decimal debitPrice = 0;
if (m_Price.DiscountType == DiscountTypeEnum.COINS &&
m_Price.CommissionType == DiscountTypeEnum.COINS)
{
//TotalDebtWithoutTax=X-Discount+Commission
debitPrice = TotalDebtWithoutTax + m_Price.Discount - m_Price.Commission;
}
else if (m_Price.DiscountType == DiscountTypeEnum.COINS &&
m_Price.CommissionType == DiscountTypeEnum.PERCENTS)
{
//TotalDebtWithoutTax=X-Discount+Commission*X/100
debitPrice = (TotalDebtWithoutTax + m_Price.Discount) / (1 + m_Price.Commission / 100);
}
else if (m_Price.DiscountType == DiscountTypeEnum.PERCENTS &&
m_Price.CommissionType == DiscountTypeEnum.COINS)
{
//TotalDebtWithoutTax=X-Discount*X/100+Commission
debitPrice = (TotalDebtWithoutTax - m_Price.Commission) / (1 - m_Price.Discount / 100);
}
else if (m_Price.DiscountType == DiscountTypeEnum.PERCENTS &&
m_Price.CommissionType == DiscountTypeEnum.PERCENTS)
{
//TotalDebtWithoutTax=X-Discount*X/100+Commission*X/100
debitPrice = TotalDebtWithoutTax / (1 - m_Price.Discount / 100 + m_Price.Commission / 100);
}
return debitPrice;
}
}
I have classes such as Invoice, PurchaseInvoice, DeliveryNote that each: 1. implements IPrice using its members. 2. implements IExtendPrice using ExtendPrice default implementation. Such class can look like:
public class Invoice : IPrice, IExtendPrice
{
public virtual decimal TotalDebt { get; set; }
public virtual decimal TaxPercent { get; set; }
public virtual decimal Discount { get; set; }
public virtual DiscountTypeEnum DiscountType { get; set; }
public virtual decimal Commission { get; set; }
public virtual DiscountTypeEnum CommissionType { get; set; }
private IExtendPrice extendPrice = null;
public Invoice()
{
extendPrice = new ExtendPrice(this);
}
public decimal TotalDebtWithoutTax { get { return extendPrice.TotalDebtWithoutTax; } }
public decimal TaxSum { get { return extendPrice.TaxSum; } }
public decimal DiscountSum { get { return extendPrice.DiscountSum; } }
public decimal CommissionSum { get { return extendPrice.CommissionSum; } }
public decimal DebitPrice { get { return extendPrice.DebitPrice; } }
}
But noe I have class that called CreditInvoice. It has the following member:
public decimal TotalCreditSumWithoutTax
{
get { return Math.Round(m_TotalCreditSum / (1 + (m_Tax / 100)), 2); }
}
Which is the same implementation like ExtendPrice's TotalDebtWithoutTax. The difference is with it's name instead of credit - debit/debt.
What is the best practice to enables the use of ExtendPrice in CreditInvoice without changing the names of its members?
Use an explicit interface implementation for that member:
class CreditInvoice : IExtendPrice
{
// ...
public decimal TotalCreditSumWithoutTax { /* ... */ }
// Only seen when accessing an instance by its IExtendPrice interface
decimal IExtendPrice.TotalDebtWithoutTax {
get { return TotalCreditSumWithoutTax; }
}
}
You have to do something like this:
public decimal TotalDebtWithoutTax { get { return TotalCreditSumWithoutTax; } }
Although when you read that, it does sound as though there are some design flaws in your code.
In the comments you make it clear that you want to implement the interface, but not implement a method named TotalDebtWithoutTax
. That's not possible. In order to implement an interface, you need to implement all the methods.
My guess is that your choice of name for TotalDebtWithoutTax
is too constraining. You are probably objecting to having to implement it with a method name TotalCreditSumWithoutTax
. How can a credit be a debit? I guess you'll need to generalise the underlying interface to remove this impedance.
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