C#泛型中怎样实现数值类型的限制与操作四则运算

Wesley13
• 阅读 1827

在C#中定义泛型可以达到代码的重复利用,但是如何将泛型方法限制为数值类型(如int,double,float 等)并对其进行进行四则运算呢?

其实:C#不支持这一点。Hejlsberg描述了不实现此特性的原因。在接受布鲁斯·埃克尔的采访时:

现在还不清楚增加的复杂性是否值得你得到的小收益。如果在约束系统中不直接支持要做的事情,可以使用工厂模式来完成。你可以Matrix<T>例如,在这方面Matrix您想要定义一个点乘积方法。当然,这意味着你最终需要了解如何将2相乘。TS,但你不能说这是一种约束,至少如果Tintdouble,或float..但你能做的就是Matrix把论点当作论据Calculator<T>,以及Calculator<T>,有一个名为multiply..你去实现它,然后把它传递给Matrix.

那么如果我们需要一个求数组和的泛型方法怎么办?

我们不妨使用下列方法实现

 public static T Sum<T>(params T[] values) where T:struct

{
    //逻辑实现部分


}

        首先我们应该知道struct的范围要远大于数值类型;即(int,float,double 等)是struct的一部分,退而求其次,我们将输入的值限制为struct,那么可以很大程度上将输入值限制;

那么struct值类型提供了如下Equals、GetType、GetHashCode、ToString四个方法,系统并无提供四则运算的方法,我们如何对其数组进行求和呢?

接下来我们不妨如下操作:

 public static T Sum<T>(params T[] values) where T:struct
        {
           if (values == null) return default(T);
            dynamic sum = default(T);
            var type = Type.GetTypeCode(values[0].GetType());
            switch (type)
            {
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                case TypeCode.Decimal:
                   {
                        dynamic vas = values;
                        for (int i = 0; i < vas.Length; i++)
                        {
                            sum += vas[i];

                        }
                    }
                    break;
                default:
                    break;

            }
            
            return sum;


            
        }

借用dynamic的特性我们可以将输入值转换成dynamic然后在进行四则运算;

特别提醒:此方法虽然可以实现数值类型的求和但是对于一些无四则运算的struct会产生异常操作,我们可以在进行数值运算前进行类型判断,若类型无四则运算操作则特别处理,

在一些取舍下,上述方法也是一个不错的方法;

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
java 泛型详解
对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下。本文参考java泛型详解、Java中的泛型方法、java泛型详解1\.概述泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。什么是泛型?为什么要使用泛型?泛型,即“参数化类型”。一提到参数,最熟
Wesley13 Wesley13
3年前
java泛型
一、实现机制java泛型实现方法为类型擦除,基于这种方法实现的泛型称为伪泛型。java泛型只在源代码中存在,在编译后的文件中替换为原生类型,并插入强制转换。(真正的泛型是应该存在于源码、编译后文件、运行期)二、擦除实例源码:List<StringtestListnewArrayList<String();
Stella981 Stella981
3年前
Gson通过借助TypeToken获取泛型参数的类型的方法
最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下。由于Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)。但是有的时候
Wesley13 Wesley13
3年前
Java泛型详解
引言Java泛型是jdk1.5中引入的一个新特性,泛型提供了编译时的类型检测机制,该机制允许程序员在编译时检测到非法的类型。泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。泛型基础
Easter79 Easter79
3年前
Thinking in java Chapter15 泛型
1与C比较2简单泛型泛型类3泛型接口4泛型方法5匿名内部类6构建复杂模型78910“泛型”意思就是:适用于许多许多的类型<h2id"1"1与C比较</h2C
Wesley13 Wesley13
3年前
C++:模板类
22.模板类22.1模板类模板是泛型编程的基础,那什么是泛型编程呢?泛型编程是一种独立于任何特定数据类型编写代码的方式。C标准模板库中的数据容器、迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。比如动态数组vector是可以存放任何类型数据的容器,我们可以定义许多不同类型的vector,比如vector<int或vect
Wesley13 Wesley13
3年前
Java泛型一览笔录
1、什么是泛型?泛型(Generics)是把类型参数化,运用于类、接口、方法中,可以通过执行泛型类型调用分配一个类型,将用分配的具体类型替换泛型类型。然后,所分配的类型将用于限制容器内使用的值,这样就无需进行类型转换,还可以在编译时提供更强的类型检查。2、泛型有什么用?泛型主要有两个好处:(1)消除显
Wesley13 Wesley13
3年前
JAVA 泛型中的通配符 T,E,K,V 傻傻分不清楚 ?
前言Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型带来的好处在没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带