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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『 再看.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)");

结果:

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

bool IsDig(object t)

    return typeof(INumber<>).IsInstanceOfType(t);

结果:

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

bool IsDig(object t)

    return t.GetType().GetInterfaces().Any(s => s.Name == typeof(INumber<>).Name);

结果:

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

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』是否数值类型的主要内容,如果未能解决你的问题,请参考以下文章

『 再看.NET7』string的进化

『 再看.NET7』泛性特性使用场景

『 再看.NET7』让json序列化体现多态

『 再看.NET7』看看required属性有什么不同

『 再看.NET7』新的访问修饰符——file

.NET周报12月第4期 2022-12-31