c# 重载运算符(ovveride operator)踩坑记,关于null比对
场景描述:
需要比对两个版本的对应对象是否完全一致(每个属性值一致),不一致的导出报表颜色标识,以便提醒后续使用报表人员。
实现思路:
对象重载ToString方法,另实现一比对基类(为了通用)重载==与!=运算符,所有比对对象继承于比对基类。
代码:
class A:C
{
public A(string a, string b)
{
AA = a;
BB = b;
}
public string AA { get; set; } public string BB { get; set; } public override string ToString()
{
return AA+BB;
}
} class B:C
{
public B() { }
public B(string a, string b)
{
AA = a;
BB = b;
}
public string AA { get; set; } public string BB { get; set; } public override string ToString()
{
return AA + BB;
}
} class C
{
public static bool operator ==(C a, C b)
{
//这里有漏洞,对象比对,如果是和null比对呢,以下。。。呵呵了
string _a = a.ToString();
string _b = b.ToString();
return _a.Length == _b.Length && _a.GetHashCode() == _b.GetHashCode() && _a == _b;
} public static bool operator !=(C a, C b)
{
return true;
}
} class Test
{
public void Compare()
{
Console.WriteLine(new A("a", null) == new A("a", "b"));//正常
Console.WriteLine(new B("a", "b") == new B("a", "b"));//正常 Console.WriteLine(new B("a", "b") == null);//额,这个是直击漏洞
}
}
怎么解决漏洞呢,第二版C类:
class C
{
public static bool operator ==(C a, C b)
{
//这里会死循环System.StackOverflowException异常
if (a == null || b == null)
{
if (a == b)
return true;
return false;
}
string _a = a.ToString();
string _b = b.ToString();
return _a.Length == _b.Length && _a.GetHashCode() == _b.GetHashCode() && _a == _b;
} public static bool operator !=(C a, C b)
{
return true;
}
}
为什么呢?等抛出异常后,明白了,在判断a==null的时候,不同样需要执行重载后的==吗?一遍一遍的执行,死循环呗。
思考一下,有没有什么解决办法?如果当前自己写的重载有问题,那能不能用没问题的重载呢?比如所有类的基类object,而object==null是不报异常的,那就考虑第三版,如下:
class C
{
public static bool operator ==(C a, C b)
{
//借用object==null来判断,类型转换,耗时
if ((a as object) == null)
{
return (b as object) == null;
}
if ((b as object) == null)
return false;
string _a = a.ToString();
string _b = b.ToString();
return _a.Length == _b.Length && _a.GetHashCode() == _b.GetHashCode() && _a == _b;
} public static bool operator !=(C a, C b)
{
return true;
}
}
我本人不通底层的东西,但是,类型转换确实耗时,我这边报表是几万条数据的比对,当然,我也没测,于是想到一重可以通过is判断类型的思路,如下:
class C
{
public static bool operator ==(C a, C b)
{
//借用is判断类型
if ((a is C) && (b is C))
{
string _a = a.ToString();
string _b = b.ToString();
return _a.Length == _b.Length && _a.GetHashCode() == _b.GetHashCode() && _a == _b;
}
return !(a is C) && !(b is C);
} public static bool operator !=(C a, C b)
{
return true;
}
}
以上是我的思路,如果哪位大神懂为什么object==null比对是没问题的,还请告知,再次谢过,欢迎大家留言。
附:!=的判断也不能只返回true,如果你的系统中用到!=去比对。。应修改为如下(只实现一种):
public static bool operator !=(C a, C b)
{
if ((a as object) == null)
return (b as object) != null;
if ((b as object) == null)
return true;
return a != b;
}
c# 重载运算符(ovveride operator)踩坑记,关于null比对的更多相关文章
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
- vue踩坑记
vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...
- 【bug记录】OS Lab4 踩坑记
OS Lab4 踩坑记 Lab4在之前Lab3的基础上,增加了系统调用,难度增加了很多.而且加上注释不详细,开玩笑的指导书,自己做起来困难较大.也遇到了大大小小的bug,调试了一整天. 本文记录笔者在 ...
- 【bug记录】OS Lab3 踩坑记
OS Lab3 踩坑记 Lab3在之前Lab2的基础上,增加了进程建立.调度和中断异常处理.其中测试包括进程建立以及进程调度部分. 由于是第一次做bug记录,而且是调试完bug后再做的记录,所以导致记 ...
随机推荐
- CS小分队第一阶段冲刺站立会议(5月12日)
昨日成果:2048整体界面效果经组员韩雪冬美化之后档次提升了好几个,我为其添加了保存并显示最高分数的功能. 遇到困难:当我想把access数据库由accdb改成mdb时,发生未知错误 ,导致数据库无法 ...
- web项目页面加载时,下拉框有值
1.我用的框架是springmvc和mybaitis 由于没有整个项目,直接就去请求的action :http://localhost:8080/ytert/test/selectStoreType ...
- 总结在Visual Studio Code创建Node.js+Express+handlebars项目
一.安装node.js环境. Node.js安装包及源码下载地址为:https://nodejs.org/en/download/ 32 位安装包下载地址 : https://nodejs.org/d ...
- 软工实践第八次作业(课堂实战)- 项目UML设计(第五组)
本次作业博客 团队信息 队名:起床一起肝活队 原组长: 白晨曦(101) 原组员: 李麒 (123) 陈德斌(104) 何裕捷(214) 黄培鑫(217) 王焕仁(233) 林志华(128) 乐忠豪( ...
- mysql---时间类型详解
mysql 日期类型 mysql 日期类型 · DATE (适用于"出生日期"等只需要年月日数据的日期字段) 日期.支持的范围为'1000-01-01'到'9999-12- ...
- Alpha冲刺阶段集合贴
第一篇:http://www.cnblogs.com/xss6666/p/8870734.html 第二篇:http://www.cnblogs.com/xss6666/p/8893683.html ...
- 软工网络15团队作业4-DAY8
每日例会 昨天的工作. 张陈东芳:可导入部分类信息,继续尝试将所有信息导入: 吴敏烽:商品类的规范化编写: 周汉麟:界面的排版继续优化: 林振斌:按照浏览历史,次数等,继续优化商品类排序: 李智:研究 ...
- Qt多线程-QThread
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread 本文地址:http://techieliang.com/2 ...
- 【Linux】- 简明Vim练习攻略
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...
- 【Nginx】均衡负载权重模式实现session数据同步
思路:把session存放到一个公共redis服务器上 每次浏览器请求服务端都会带上cookie,因为使用的是权重负载均衡方案,因此nginx反向代理服务器会把请求发放到不同的服务端,服务端用cook ...