.net泛型通用函数的特殊问题的解决方法
自从2.0版本的net framework推出之后泛型(Generic)得到了广泛好评。它不必像object类型一样性能上因为“拆箱”或者“装箱”得到损失,同时在编译语法检测阶段就可以实时检测出传入或者传出的类型是否符合特定条件。
但“金无赤足,人无完人”——在我们享受这些幸福编程的同时,泛型自身类型的不确定也带来了一个显著的问题——无法进行运算符重载。譬如现在我要写一个函数(一个通用的选择排序算法,使用泛型T),该怎么办呢?如果你简单使用这样的代码(C#如下):
自从2.0版本的net framework推出之后泛型(Generic)得到了广泛好评。它不必像object类型一样性能上因为“拆箱”或者“装箱”得到损失,同时在编译语法检测阶段就可以实时检测出传入或者传出的类型是否符合特定条件。
但“金无赤足,人无完人”——在我们享受这些幸福编程的同时,泛型自身类型的不确定也带来了一个显著的问题——无法进行运算符重载。譬如现在我要写一个函数(一个通用的选择排序算法,使用泛型T),该怎么办呢?如果你简单使用这样的代码(C#如下):
编译之后很快发现提示“运算符‘>'无法作用于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]=templ
flag = 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#代码如下):
.net泛型通用函数的特殊问题的解决方法的更多相关文章
- 泛型 Generic 类型擦除引起的问题及解决方法
参考:http://blog.csdn.net/lonelyroamer/article/details/7868820#comments 因为种种原因,Java不能实现真正的泛型,只能使用类型擦除来 ...
- 使用Ef查询出现的问题The cast to value type 'System.Boolean' failed because the materialized value is null.的解决方法
把值类型的系统.布尔的失败是因为物化值是null.结果类型的泛型参数或查询必须使用可空类型. 解决方法: 请确保你查询中的字段值不为空或者做为空判断
- Spring JdbcTemplate的queryForList(String sql , Class<T> elementType)返回非映射实体类的解决方法
Spring JdbcTemplate的queryForList(String sql , Class<T> elementType)易错使用 一直用ORM,今天用JdbcTemplate ...
- IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法
直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...
- MVVM框架从WPF移植到UWP遇到的问题和解决方法
MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...
- iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法
问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...
- python中IndentationError: expected an indented block错误的解决方法
IndentationError: expected an indented block 翻译为IndentationError:预期的缩进块 解决方法:有冒号的下一行要缩进,该缩进就缩进
- js闭包for循环总是只执行最后一个值得解决方法
<style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...
- mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!
mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法! 修改mysql5.7的配置文件即可解决,方法如下: linux版:找到mysql的安装路径进入默认的为/usr/shar ...
随机推荐
- UVA 10168 Summation of Four Primes(数论)
Summation of Four Primes Input: standard input Output: standard output Time Limit: 4 seconds Euler p ...
- Linux内核部件分析 原子性操作atomic_t
在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的.在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的.为了弥补 ...
- JS JSOP跨域请求实例详解
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题.这篇文章主要介绍了JS JSOP跨域请求实例详解的相关资料,需要的朋友可以参考下 ...
- MVC中Area的另一种用法
[摘要]本文只是为一行代码而分享 context.MapRoute("API", "api/{controller}/{action}", new { }, n ...
- 全栈工程师的武器——MEAN(转)
MongoDB MongoDB也就是常说的NoSQL数据库.可以认为它是文档结构的数据库,而不是由行.列.表组成的数据库.基本的用法是存储JSON数据,这很适合JavaScript程序.它是非关系型. ...
- 论Top与ROW_NUMBER读取第一页的效率问题及拼接sql查询条件
http://www.cnblogs.com/Leo_wl/p/4921799.html SELECT TOP * FROM users WHERE nID> And nID< ORDER ...
- Groovy小结:java调用Groovy方法并传递参数
Groovy小结:java调用Groovy方法并传递参数 @(JAVA总结) 1. 场景描述 在网上查了资料发现,java有三种方式调用groovy脚本.但是真正在实际的服务器环境中,嵌入groovy ...
- /proc/version 的生成过程
/proc/version 的生成过程 通常我们cat /proc/version时,会显示kernel相关的版本.编译等信息 那么问题来了,这些信息是怎么生成的呢? /proc/version文件是 ...
- deepin linux 下C开发环境配置
# deepin linux 下C开发环境配置 ## 前言-----------------------------deepin操作系统商店默认提供了 eclipse for c\c++但是系统没有提 ...
- H4CK1T CTF 2016 Mexico-Remote pentest writeup
进去网站之后发现连接都是包含类型的,就能想到文件包含漏洞(话说刚总结过就能遇到这题,也算是复习啦) 这里用php://filter/read=convert.base64-encode/resourc ...