2010-04-21 3 views
1

У меня есть вариант на классе количества (Fowler), который предназначен для облегчения преобразования между единицами. Тип объявлен как:Рефакторинг с дженериками

public class QuantityConvertibleUnits<TFactory> 
    where TFactory : ConvertableUnitFactory, new() { ... } 

Для того, чтобы сделать математические операции между разнородными единицами, преобразовать правую часть операции на эквивалентное количество независимо от блока левая находится, и делать математику на сумму (которая является двойной) перед созданием нового количества. Внутри родового класса Количества, у меня есть следующий:

protected static TQuantity _Add<TQuantity>(TQuantity lhs, TQuantity rhs) 
     where TQuantity : QuantityConvertibleUnits<TFactory>, new() 
    { 
     var toUnit = lhs.ConvertableUnit; 
     var equivalentRhs = _Convert<TQuantity>(rhs.Quantity, toUnit); 
     var newAmount = lhs.Quantity.Amount + equivalentRhs.Quantity.Amount; 
     return _Convert<TQuantity>(new Quantity(newAmount, toUnit.Unit), toUnit); 
    } 

    protected static TQuantity _Subtract<TQuantity>(TQuantity lhs, TQuantity rhs) 
     where TQuantity : QuantityConvertibleUnits<TFactory>, new() 
    { 
     var toUnit = lhs.ConvertableUnit; 
     var equivalentRhs = _Convert<TQuantity>(rhs.Quantity, toUnit); 
     var newAmount = lhs.Quantity.Amount - equivalentRhs.Quantity.Amount; 
     return _Convert<TQuantity>(new Quantity(newAmount, toUnit.Unit), toUnit); 
    } 

    ... same for multiply and also divide 

Мне нужно, чтобы получить право печатания для бетона Количества, так пример надстройки цита выглядит следующим образом:

 public static ImperialLengthQuantity operator +(ImperialLengthQuantity lhs, ImperialLengthQuantity rhs) { return _Add(lhs, rhs); } 

Вопрос заключается в эти подробные методы в классе Quantity. Единственным изменением между кодом является математический оператор (+, -, * и т. Д.), Поэтому кажется, что должен быть способ реорганизации их в общий метод, но я просто не вижу его.

Как я могу реорганизовать этот код?

Cheers,
Berryl

ответ

4

Вы могли бы написать

protected static TQuantity _Operator<TQuantity>(TQuantity lhs, TQuantity rhs, 
             Func<double, double, double> op) 
     where TQuantity : QuantityConvertibleUnits<TFactory>, new() 
{ 
     var toUnit = lhs.ConvertableUnit; 
     var equivalentRhs = _Convert<TQuantity>(rhs.Quantity, toUnit); 
     var newAmount = op(lhs.Quantity.Amount,equivalentRhs.Quantity.Amount); 
     return _Convert<TQuantity>(new Quantity(newAmount, toUnit.Unit), toUnit); 
    } 

и вызвать эту функцию в _Add и т.д., используя (d1, d2) => d1 + d2 в качестве дополнительного параметра.

+0

Сладкий раствор. Благодаря! – Berryl

0

Там нет прямой родовой поддержки оператора в C#. Вы можете поддельной его в C# 4.0 на .NET 4 с использованием dynamic - т.е.

TQuantity newAmount = (dynamic)lhs.Quantity.Amount - 
         (dynamic)equivalentRhs.Quantity.Amount; 

Или вы можете сделать это в .NET 3.5 и выше, с использованием MiscUtil, который обеспечивает an Operator class со служебными методами (который поддерживает пользовательские и встроенные операторы):

TQuantity newAmount = Operator.Add(lhs.Quantity.Amount, 
            equivalentRhs.Quantity.Amount); 

В качестве альтернативы; обеспечивают интерфейс ICalculator<T> и записывают реализации для каждого типа.

Смежные вопросы