『 再看.NET7』是否数值类型

很多时候,会判断一个值是否为数值类型,数值类型是可以进行算术运算的,表示格式也比较统一,所以在做通用功能时会用到。下面给出了几种用法。

第一版:通用用法,设置具体类型逐一进行判断,这种做法可以灵活设置类型,缺点也是想增加类型,也得人工增加。.

bool IsDig(object t) => t switch{    short => true,    int => true,    long => true,    Int128 => true,    double => true,    float => true,    Half => true,    decimal => true,    ushort => true,    uint => true,    ulong => true,    UInt128 => true,    _ => false,};
Console.WriteLine("--------嫡系---------");Half h = (Half)43210.123456789;Console.WriteLine($"{h.GetType().Name},{IsDig(h)}");
var f = 1.2f;Console.WriteLine($"{f.GetType().Name},{IsDig(f)}");
var d = 1.2d;Console.WriteLine($"{d.GetType().Name},{IsDig(d)}");
var dec = 1.2m;Console.WriteLine($"{dec.GetType().Name},{IsDig(dec)}");
ushort us = 10;Console.WriteLine($"{us.GetType().Name},{IsDig(us)}");
uint ui = 10;Console.WriteLine($"{ui.GetType().Name},{IsDig(ui)}");
ulong ul = 10;Console.WriteLine($"{ul.GetType().Name},{IsDig(ul)}");
UInt128 ubi = 1020232321211;Console.WriteLine($"{ubi.GetType().Name},{IsDig(ubi)}");
short si = 10;Console.WriteLine($"{si.GetType().Name},{IsDig(si)}");
int i = 10;Console.WriteLine($"{i.GetType().Name},{IsDig(i)}");
long l = 10;Console.WriteLine($"{l.GetType().Name},{IsDig(l)}");
Int128 bi = 1020232321211;Console.WriteLine($"{bi.GetType().Name},{IsDig(bi)}");
Console.WriteLine("--------本家---------");BigInteger bgi = 12313213213213212;Console.WriteLine($"{bgi.GetType().Name},{IsDig(bgi)}");
Console.WriteLine("---------娘家--------");char c = 'c';Console.WriteLine($"{c.GetType().Name},{IsDig(c)}");
var b = (byte)1;Console.WriteLine($"{b.GetType().Name},{IsDig(b)}");
Console.WriteLine("--------外人---------");var t = true;Console.WriteLine($"{t.GetType().Name},{IsDig(t)}");
var str = "abcd";Console.WriteLine($"{str.GetType().Name},{IsDig(str)}");

结果:

『 再看.NET7』是否数值类型

方案二:在.NET 7中,官方引入了一个INumber的接口,实现了这个接口的简单类型,都是官方规定的数值类型,借助这一点,可以判断是否是数值类型。

bool IsDig(object t){    return typeof(INumber<>).IsInstanceOfType(t);}

结果:

『 再看.NET7』是否数值类型

方案三:有的时候,我们会用到BigInteger这个新的表示大数值的类型,但如果用方案二,这个类型就没有算在其中,那又想把它算在数值类型中,就得另谋出路了。

bool IsDig(object t){    return t.GetType().GetInterfaces().Any(s => s.Name == typeof(INumber<>).Name);}

结果:

『 再看.NET7』是否数值类型

上面三种方式都是实现判断数值类型的,但它们的性能如何呢?下面做了个简单对比:

public class TestIsDIg{    object[] datas;
    public TestIsDIg()    {        datas = new object[] { 1, 1l, 1d, 1f, 1m };    }    [Benchmark]    public bool IsDig3()    {        var result = true;        foreach (var t in datas)        {            result = result && t.GetType().GetInterfaces().Any(s => s.Name == typeof(INumber<>).Name);        }        return result;    }    [Benchmark]    public bool IsDig2()    {        var result = true;        foreach (var t in datas)        {            return typeof(INumber<>).IsInstanceOfType(t);        }        return result;    }    [Benchmark]    public bool IsDig1()    {        var result = true;        foreach (var t in datas)        {            return IsDig(t);        }        return result;        bool IsDig(object t) => t switch        {            short => true,            int => true,            long => true,            Int128 => true,            double => true,            float => true,            Half => true,            decimal => true,            ushort => true,            uint => true,            ulong => true,            UInt128 => true,            _ => false,        };    }}

结果:

『 再看.NET7』是否数值类型

看来方案一还是靠谱的,方案三是最不靠谱的,方案二可以说是性价比较好的。