Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a method in C# that can take double, decimal, and floats without repeating code

Tags:

c#

generics

dry

I'm trying to not repeat code unnecessarily. I have this method which I want to return true or false based on a basic calculation. The arguments for the value could be double, float, decimal.

This was my (failed) attempt. Any guidance would be appreciated.

private bool DoMyThingGeneric(Type type, object value)
{
    // I'm trying to do something like this:
    // cast "value" to "type"
    var constructed = type.MakeGenericType();

    object obj = Activator.CreateInstance(constructed);

    // assign "value" to "d" - THIS DOESN'T WORK
    var endVal = obj as typeof(type);


    if (Math.Floor(endVal * 1000) == endVal * 1000)
    {
        return true;
    }

    return false;
}

private bool DoMyThing(decimal x)
{
    DoMyThingGeneric(x.GetType(), x);

    return false;
}

private bool DoMyThing(float x)
{
    DoMyThingGeneric(x.GetType(), x);

    return false;
}

private bool DoMyThing(double x)
{
    DoMyThingGeneric(x.GetType(), x);

    return false;
}
like image 815
Gezim Avatar asked Jan 11 '23 01:01

Gezim


2 Answers

Repeat the code. Or cast.

As generics can not have operators.... there is no alternarive.

like image 163
TomTom Avatar answered Jan 21 '23 15:01

TomTom


In C#, you have the following options.

  1. Repeat the code.
  2. Implement the operation using the widest required type, and then cast the result (e.g. if you need to support just double and float, you could implement support for float by calling the double method and casting the result to float). This is not always an option since the range and precision of the various types doesn't always overlap.
  3. Create a private implementation method that uses dynamic arguments. This would avoid some code duplication at the expense of type safety and have a substantial performance impact.
  4. Create an interface defining your methods, and use reflection to generate the appropriate code to implement the various interface methods dynamically. This would be less maintainable than the first option, challenging to implement correctly, and almost certainly longer than just duplicating the code.

Most application code involving a choice between float, double, and decimal is either so simple that it is easily duplicated, or so performance sensitive that duplication is required to meet the target goals. Repeating the code is almost always the best available option.

like image 45
Sam Harwell Avatar answered Jan 21 '23 15:01

Sam Harwell