Использование генериков в C#


Мне любопытно о generics в C# и хотел бы знать Ваше мнение

  • правильно ли я использовать дженерики
  • о том, как улучшить этот код

Например, у меня есть платежная система какой-то магазин.

Так у меня PaymentSystem класс:

public class PaymentSystem
{        

    public T MakePayment<T>(T paymentSystem) where T : PaymentCompany
    {
        try
        {
            paymentSystem.CalculatedSum = paymentSystem.CalcSum();
        }
        catch (Exception ex)
        {
            var message = ex.Message;

        }

        return paymentSystem;
    }
}

и абстрактный класс для PaymentCompany:

public abstract class PaymentCompany
{
    public PaymentCompany(decimal amount)
    {
        Amount = amount;
    }

    public decimal Amount { get; set; }

    public decimal CalculatedSum { get; set; }        

    public virtual decimal CalcSum()
    {
        return Amount;
    }

}

и оплата:

public class MasterCard : PaymentCompany
{
    public MasterCard(decimal amount) : base(amount)
    {

    }

    public int CVV { get; set; }


    public override decimal CalcSum()
    {           
        return (base.CalcSum() + 5)/0;
    }

}


public class Visa : PaymentCompany
{
    public string KeyWord { get; set; }

    public Visa(decimal amount) : base(amount){}
}

И я называю MakePayment способ такой:

static void Main(string[] args)
{
     var paymentSystem = new PaymentSystem();
     var result = paymentSystem.MakePayment(new MasterCard(15));     
}

Ребята, сделайте пожалуйста обзор код, и ответить на мои вопросы:

  • правильно ли я использовать дженерики
  • как улучшить этот код(я должен обрабатывать исключения в производных классах(MasterCard, ...))

Все ответы будут высоко оценены!



129
-3
задан 11 марта 2018 в 06:03 Источник Поделиться
Комментарии
1 ответ

Вы сделали неверное предположение, что вы должны вернуться обновленные платежные компании, потому что вы меняете значение CalculatedSum. PaymentCompany это класс, и поэтому ссылочный тип. Ссылка не меняется при изменении поля и свойства объекта, на которые он ссылается.

MakePayment может быть void тип возврата и не должны быть универсальными.

public class PaymentSystem
{
public void MakePayment(PaymentCompany paymentCompany)
{
try
{
paymentCompany.CalculatedSum = paymentCompany.CalcSum();
}
catch (Exception ex)
{
//TODO: handle exception
}
}
}

Вы можете назвать это с:

static void Main(string[] args)
{
var paymentSystem = new PaymentSystem();
var company = new MasterCard(15);
paymentSystem.MakePayment(company);
decimal result = company.CalculatedSum;
}


Но дизайн не является оптимальным. Что такое собственность CalculatedSum хорошо для? Брось его и вернуть результат сразу!

public class PaymentSystem
{
public decimal MakePayment(PaymentCompany paymentCompany)
{
try
{
return paymentCompany.CalcSum();
}
catch (Exception ex)
{
//TODO: handle exception
}
}
}

static void Main(string[] args)
{
var paymentSystem = new PaymentSystem();
var company = new MasterCard(15);
decimal result = paymentSystem.MakePayment(company);
}


Другим вариантом является CalcSum С типом возврата Void, а позволить его назначить CalculatedSum внутренне. CalculatedSum тогда есть отдельный сеттер.

public abstract class PaymentCompany
{
public PaymentCompany(decimal amount)
{
Amount = amount;
}

public decimal Amount { get; set; }

public decimal CalculatedSum { get; private set; }

public virtual void CalcSum()
{
CalculatedSum = Amount;
}
}

1
ответ дан 11 марта 2018 в 09:03 Источник Поделиться