реализовать интерфейс, но с разными именами членов - PullRequest
5 голосов
/ 27 июля 2011

У меня есть интерфейс IPrice:

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

У меня есть интерфейс IExtendPrice и его реализация по умолчанию:

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

У меня есть классы, такие как Invoice, PurchaseInvoice, DeliveryNote, каждый из которых: 1.реализует IPrice с использованием своих членов.2. реализует IExtendPrice, используя реализацию по умолчанию ExtendPrice.Такой класс может выглядеть так:

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

Но нет, у меня есть класс, который называется CreditInvoice.Он имеет следующий член:

    public decimal TotalCreditSumWithoutTax
    {
        get { return Math.Round(m_TotalCreditSum / (1 + (m_Tax / 100)), 2); }
    }

Это та же реализация, что и у TotalDebtWithoutTax в ExtendPrice.Разница заключается в том, что вместо названия «кредит - дебит / долг» используется его имя.

Каков наилучший способ использования ExtendPrice в CreditInvoice без изменения имен его членов?

Ответы [ 3 ]

14 голосов
/ 27 июля 2011

Используйте явную реализацию интерфейса для этого члена:

class CreditInvoice : IExtendPrice
{
    // ...
    public decimal TotalCreditSumWithoutTax { /* ... */ }


    // Only seen when accessing an instance by its IExtendPrice interface
    decimal IExtendPrice.TotalDebtWithoutTax {
        get { return TotalCreditSumWithoutTax; }
    }
}
4 голосов
/ 27 июля 2011

Вы должны сделать что-то вроде этого:

public decimal TotalDebtWithoutTax { get { return TotalCreditSumWithoutTax; } }

Хотя когда вы читаете это, звучит так, как будто в вашем коде есть некоторые недостатки дизайна.


В комментариях вы даете понять, что хотите реализовать интерфейс, но не реализует метод с именем TotalDebtWithoutTax.Это невозможно.Чтобы реализовать интерфейс, вам нужно реализовать все методы.

Я предполагаю, что ваш выбор имени для TotalDebtWithoutTax слишком ограничен.Возможно, вы возражаете против того, чтобы реализовать его с именем метода TotalCreditSumWithoutTax.Как кредит может быть дебетом?Я предполагаю, что вам нужно будет обобщить базовый интерфейс, чтобы удалить этот импеданс.

1 голос
/ 27 июля 2011

Вы ищете шаблон адаптера .Это создает адаптер, который реализует интерфейс и затем вызывает существующие методы для адаптированного типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...