C#C
C#4y ago
Alexicon

Using the new INumber interface to determine if an object is a number without having the generic arg

With .net7 we now have the INumber<TSelf> interface which is pretty cool, and I thought I found a place where I might be able to use it for the first time. However, I am running into some trouble.

I am wondering if there is any way to know if some ‘object’ is a number and return the ‘One’ abstract static property from the INumber<TSelf> interface it would implement. The issue is I do not have a generic argument to plug in for TSelf, and I cannot add one in this case since the method I am working on is an override of a method outside of my control and it does not have a T generic argument.

Here is a cut-down example as a x-unit test of what I am doing and what I have tried.
[Theory]
[InlineData(1)]
[InlineData(2.2)]
[InlineData("not a number")]
public object? MyMethod(object something)
{
    Type numberType = typeof(INumber<>);
    Type somethingType = something.GetType();

    //this fails if something is not a number since TSelf must implement INumber<TSelf> :(
    Type genericNumberType = numberType.MakeGenericType(somethingType);

    bool isNumber = something
        .GetType()
        .IsAssignableTo(genericNumberType);

    if (isNumber)
    {
        //all of these and more result in nothing
        //i have tried many diffrent permutations of BindingFlags for each of these
        var nothing = genericNumberType.GetProperties(BindingFlags.Static);
        var alsoNothing = genericNumberType.GetMembers(BindingFlags.Static);
        var againNothing = something.GetType().GetMembers(BindingFlags.Static);

        //the crux of what i want:
        //INumber<int>.One = 1
        //INumber<double>.One = 1.0
        object? result = somethingType
            .GetProperty("One")?
            .GetValue(something);

        return result;
    }

    return null;
}

Unfortunately, with INumber<TSelf> being so new there is not a lot of information about it online so before I give up, I figured I would see if anyone here knows how to achieve this.
Was this page helpful?