Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to convert numbers into generic type?

This is how I would like to be able to write my code. MethodB is just a dummy here, all we care about is that it’s returning type T.

public static class ClassA<T> where T: struct, INumber<T>
{
    public static T MethodA( T[][] matrix, T[] vector)
    {
        T result = T.Zero;
        int m = matrix.Length;
        for(int i = 0; i < m; i++)
        {
            result += MethodB( matrix[i], vector);
        }
        return result / ( m * 2 + 1);
    }

    public static T MethodB(T[] vector1, T[] vector2)
    {
        T result = T.One;
        return result;
    }
}

The problem is the return statement of MethodA. I run into CS0019. To fix this I would like to convert m into type T. I know that all T, which will ever be used, are going to be numbers which should allow for a constructor using m as a single argument. So I would like to have a way to convert m.

A workaround to my problem I found is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

public static class ClassA<T> where T: struct, INumber<T>
{
    public static T MethodA( T[][] matrix, T[] vector)
    {
        T result = T.Zero;
        int m = matrix.Length;
        for(int i = 0; i < m; i++)
        {
            result += MethodB( matrix[i], vector);
        }
        T convertedM = CreateT( m * 2 + 1);
        return result / convertedM;
    }

    public static T MethodB( T[] vector1, T[] vector2)
    {
        T result = T.One;
        return result;
    }

    public static T CreateT( int i)
    {
        T type = new T();
        if (type is double)
        {
            double d =(double) i;
            return (T)((object)d);
        }
        if (type is float)
        {
            float d =(float) i;
            return (T)((object)d);
        }
        //here would be a long list of different number types.
        throw new NotImplementedException();
    }        
}

This seems like a suboptimal solution to me though, since I have to check against all possible types. It feels like I am missing the obvious solution, like having an interface that makes sure int conversion is implemented for all T, but I don’t know how to do that. I would like to be able to add different number systems and use the oney given by the language.

What I tried:

  1. I looked through the documentation for INumbers, but couldn’t find anything usefull for this case.
  2. Then I found the work around and implemented it, so now it’s at least working.
  3. Afterwards I tried to write my own interface and implement it, but I couldn’t figure out how to implement the interface for something already given like doubles.

>Solution :

You can use one of the CreateChecked, CreateTruncating or CreateSaturating methods on the INumber<T> type.

For example:

return result / T.CreateChecked(m * 2 + 1);

CreateChecked: Creates an instance of the current type from a value, throwing an overflow exception for any values that fall outside the representable range of the current type.

CreateTruncating: Creates an instance of the current type from a value, truncating any values that fall outside the representable range of the current type.

CreateSaturating: Creates an instance of the current type from a value, saturating any values that fall outside the representable range of the current type.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading