Refactoring exercise with generics

Posted by Berryl on Stack Overflow See other posts from Stack Overflow or by Berryl
Published on 2010-04-21T14:37:29Z Indexed on 2010/04/21 14:43 UTC
Read the original article Hit count: 301

Filed under:
|
|

I have a variation on a Quantity (Fowler) class that is designed to facilitate conversion between units. The type is declared as:

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

In order to do math operations between dissimilar units, I convert the right hand side of the operation to the equivalent Quantity of whatever unit the left hand side is in, and do the math on the amount (which is a double) before creating a new Quantity. Inside the generic Quantity class, I have the following:

    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

I need to get the typing right for a concrete Quantity, so an example of an add op looks like:

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

The question is those verbose methods in the Quantity class. The only change between the code is the math operator (+, -, *, etc.) so it seems that there should be a way to refactor them into a common method, but I am just not seeing it.

How can I refactor that code?

Cheers,
Berryl

© Stack Overflow or respective owner

Related posts about c#

Related posts about generics