泛型通用函数的一些特殊问题的解决方法

  首先先感谢MSDN中的一些优秀的外国友人精彩的回答,我从那里也受益良多,写此博文。

  自从2.0版本的net framework推出之后泛型(Generic)得到了广泛好评。它不必像object类型一样性能上因为“拆箱”或者“装箱”得到损失,同时在编译语法检测阶段就可以实时检测出传入或者传出的类型是否符合特定条件。

  但“金无赤足,人无完人”——在我们享受这些幸福编程的同时,泛型自身类型的不确定也带来了一个显著的问题——无法进行运算符重载。譬如现在我要写一个函数(一个通用的选择排序算法,使用泛型T),该怎么办呢?如果你简单使用这样的代码(C#如下):

//从小到大,改进型选择排序算法public static void Sort<T>(T[] array)
{bool flag = false; //标记是否已经排序for(int i=0;i<array.Length-1;++i){flag = false;  //每次假定都已经排序,无须再排序for(int j=i+1;i<array.Length;++j){if(array[i]>array[j]){int temp = array[i];array[i]=array[j];array[j]=templflag = true; //已经排序
                }}if(!flag){break;}}
}

  编译之后很快发现提示“运算符‘>’无法作用于T”一类的提示。

  为什么呢?我们知道,凡是可以进行大于、小于比较的类型肯定都定义了运算符重载。一般类必须为此定义方可进行比较,不然大于号或者小于号(或者其它运算符)无法知道如何比较而发生错误。那么泛型因为事先都不知道什么类型?编译器检查器自然无法推断你运行时动态传入的这个类型一定保证是实现了运算符重载,严格语法检查情况下就自然报错。

  怎么办呢?强制规定泛型T必须实现比较器(强制T必须实现IComparable,或者类似接口)。

public static void Sort<T>(T[] array)where T:IComparable
{bool flag = false; //标记是否已经排序for(int i=0;i<array.Length-1;++i){flag = false;  //每次假定都已经排序,无须再排序for(int j=i+1;i<array.Length;++j){if(array[i].Compare(array[j])>0){int temp = array[i];array[i]=array[j];array[j]=templflag = true; //已经排序
                }}if(!flag){break;}}
}

  一旦对泛型进行约束,那么泛型必然是实现该接口的类,必然拥有此方法(Compare方法返回结果int类型,如果大于0表示前面一个数字大于后面一个)。

  当然,微软类库中有一个Comparer静态类,已经实现了此接口可以直接进行比较(http://msdn.microsoft.com/zh-cn/library/system.collections.comparer.comparer.aspx),因此我们也可以选择直接使用这个静态类中的Compare方法得到结果。

  【例2】实现一个通用的“+”——即如果传入的字符串,则自动按照字符串进行字符拼接;如果传入的是其它基本类型(int,double等),则返回相加结果。

  微软没有为“+”预定义接口,因此无法直接使用接口的方式来做(当然你自己强制定义一个,也可以如法炮制)。我们现在换一个方法——使用表达式树(C#代码如下):

public static T Add<T>(T a, T b){Expression left = Expression.Constant(a);Expression right = Expression.Constant(b);Type t = typeof(T);Expression value;if (t is string)){value = Expression.Constant(a.ToString()+b.ToString());}else{value = Expression.Add(left, right);}Expression<Func<T>> addExp = Expression.Lambda<Func<T>>(value);Func<T> addFunc = addExp.Compile();return addFunc();}

  动态判断T是string还是其它基本类型,然后调用不同的方法组合成为表达式树,动态编译成为一个Func表达式,返回结果即可。

      另外一种思路就是说把泛型T先强制转化成ValueType(检测是否是该类,这里提醒诸位读者——一切基本值类型,包括自定义值类型都是默认继承于ValueType)。然后逐一判断是否是int还是什么其它类型,代码如下(C#):

public static T Add<T>(T a, T b)where T:class{var result1 = a as ValueType;var result2 = b as ValueType;//All can be converted to struct type and do addingif (result1 != null && result2 != null){if(T is int){return ((int)result1 + (int)result2) as T;}//其它各个判断语句……
            }return (a.ToString() + b.ToString()) as T;}

转载于:https://www.cnblogs.com/ServiceboyNew/archive/2013/02/27/2934588.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go-json 实例

环境: Win7_x64 go1.6.2 package mainimport "encoding/json" import "fmt" import "os"// 我们使用两个结构体来演示自定义数据类型的JSON数据编码和解码。 type Response1 struct {Page intFruits []string } type Response2 struct {Pag…

将文件流blob或文件file读取成url

let url URL.createObjectURL(file.raw) //将文件转化成url//或者let url URL.createObjectURL(blob) //将文件流转化成url 注意这个blob一般是通过读取后端接口文件流 设置 responseType: blob 然后返回得到的blob

20145228 《信息安全系统设计基础》第0周学习总结

阅读博客感想 •经过上学期几个月的JAVA学习&#xff0c;收获的不仅仅是JAVA知识&#xff0c;更多的是我们自学一门课程的方法和能力。学习知识也不是死学&#xff0c;勤动手&#xff0c;多练习才是至关重要的。 •当处于健身教练和健身员的师生关系时&#xff0c;才是学习效率…

解决vue-pdf报错TypeError: Cannot read properties of undefined (reading ‘catch‘)

使用vue-pdf插件后&#xff0c;报错 解决方法&#xff1a;找到node_modules/vue-pdf/src/pdfjsWrapper.js文件&#xff0c;注释掉下面的代码

go 线程同步

代码来源于《Go语言开发教程》 // 线程同步: sync.Mutexpackage mainimport ("errors""fmt""sync" )type MyMap struct {mp map[string]intmutex *sync.Mutex }func (this *MyMap) Get(key string) (int, error) {this.mutex.Lock()i, ok : t…

中小企业如何提高售前,售中,售后客服质量?

企业产品出现差评、售后、维权、退款等售后问题总是让客服人员头疼&#xff0c;而且这些差评对企业的影响却日益重要&#xff0c;但是任何事情都是把双刃剑&#xff0c;处理好这些售后问题&#xff0c;不但会提升客户满意度&#xff0c;还会在这些售后问题中&#xff0c;总结出…

XMLHttpRequest 的 responseType 属性详解

XMLHttpRequest.responseType 属性是一个枚举类型的属性&#xff0c;返回响应数据的类型。它允许我们手动的设置返回数据的类型。如果我们将它设置为一个空字符串&#xff0c;它将使用默认的"text"类型。 当将responseType设置为一个特定的类型时&#xff0c;你需要确…

go 打印当前时间

go打印当前时间&#xff0c;Format好奇葩&#xff01; // 打印当前时间package mainimport ("fmt""time" )func main() {fmt.Println(time.Now().Format("2006-01-02 15:04:05")) }运行结果&#xff1a; E:\program\go\src\hw>go run h1.go 2…

electron打包

1、全局安装electron-packager npm install -g electron-packager 2、在项目目录下执行命令 electron-packager ./ --platformwin32 --archia32--platform 是发布平台win32指windows平台 linux darwin--archia32 指32位windows 64位的则为x64 3 notice package.json里面的name字…

WPR-007:WPF中窗体的透明设置

一般使用WindowStyle&#xff0c;Background&#xff0c;AllowsTransparency&#xff0c;Opacity来进行设置。 1、设置Opacity控制整个窗口的透明&#xff0c;包括上面的控件 Window x:Class"TestTransparentWindow.MainWindow" xmlns"http://schemas.m…

element中el-input无法输入

element 的 el-input 组件&#xff0c;由于组件嵌套了层次&#xff0c;导致组件无法及时刷新 解决办法&#xff1a; 使用 input &#xff0c;在输入时进行强制刷新 <el-input input"forceUpdate" v-model"status" placeholder"请输入状态">…

浅谈项目管理中的四要素

项目管理一直是一个老生常谈的问题&#xff0c;我们身边项目时时刻刻发生&#xff0c;大到火箭上天&#xff0c;小到家庭装修。老K作为技术出身&#xff0c;大大小小也做了不下50个项目&#xff0c;这里老K从IT的角度&#xff0c;带领大家用理论的知识分享如何做好一个项目。 …

万立快速开发平台——软件制作大师

万立快速开发平台&#xff0c;是一款国内最好用的快速开发平台&#xff0c;使用者不需要懂技术&#xff0c;不用写代码&#xff0c;可以快速地开发出强大的管理软件&#xff0c;例如ERP&#xff0c;OA&#xff0c;CRM&#xff0c;HRM等等软件。 万立快速开发平台&#xff0c;能…

Memcached缓存在.Net 中的使用(memcacheddotnet)

From: http://www.cnblogs.com/xibei666/p/4863604.html 缓存对于提高大数据量的网站性能无疑不是一个很好的解决方案&#xff0c;针对缓存的使用网上同仁介绍很多&#xff0c;再次我仅仅分享一下自己对Memcached使用的简单介绍。Memchached的使用通过第三方DLL来完成&#xff…

js获取节点的DOM操作

一直感觉DOM节点什么的乱七八糟的不能理解&#xff0c;可能博客也没办法写清楚&#xff0c;只能把知道的一些信息大致写下来慢慢再补充了。 HTML DOM类型 Node类型 Javascript中的所有节点类型都继承自Node类型&#xff0c;因此所有节点类型都共享着相同的基本属性和方法。 除I…

git合并代码冲突

场景&#xff1a;多人共同更改同一文件代码时候&#xff0c;可能回引发代码冲突。此时需要选择某一方或者双方代码进行合并。 采用当前更改&#xff1a;就是保留本地修改。 采用传入的更改&#xff1a;就是选择线上已有的覆盖更改。 保留双方更改&#xff1a;就是两份都保存。

[转]T4模版引擎之基础入门

本文转自&#xff1a;http://www.cnblogs.com/lzrabbit/archive/2012/07/15/2591085.html 额&#xff0c;T4好陌生的名字&#xff0c;和NuGet一样很悲催&#xff0c;不为世人所熟知&#xff0c;却又在背后默默无闻的奉献着&#xff0c;直到现在我们项目组的人除了我之外&#x…

请问WCF 跟 WebService之间异同

From: http://tommyhu.cn/wcf-WebService-qu-bie/ 问题&#xff1a; WCF与 Web Service的区别是什么&#xff1f; 和ASP.NET Web Service有什么关系&#xff1f; WCF与ASP.NET Web Service的区别是什么&#xff1f; 这是很多.NET开发人员容易搞错的问题。面试的时候也经常遇到…

报错 Cannot read properties of undefined (reading ‘ajax‘); Cannot read property ‘ajax‘ of undefined

jQuery中使用ajax发送请求&#xff0c;报错 Cannot read properties of undefined (reading ajax)&#xff1b; Cannot read property ajax of undefined 错误代码 $.ajax({type:"POST",url:"pageServlet",data:jsonData,dataType:"json",succe…

「初步」Spring与commons的BeanUtil.copyProperties

2019独角兽企业重金招聘Python工程师标准>>> ###org.apache.commons.beanutils.BeanUtils 的是 public static void copyProperties(Object dest, Object orig) throws###org.​springframework.​beans.​BeanUtils 的是 public static void copyProperties(Object…