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后再做的记录,所以导致记 ...
随机推荐
- pspo过程文档
项目计划总结: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- CS小分队第二阶段冲刺站立会议(5月27日)
昨天成果:昨日有些小意外,导致没有按照原定计划工作.昨天为扫雷游戏增加了新的失败特效,只要玩家点到地雷,所有的地雷都会依次出现两帧的爆炸效果,并伴随声音. 今日计划:排除一些现有程序的bug.. 遇到 ...
- web.config详解(转载)
该文为转载 原文地址:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.c ...
- LAMP 系统服务搭建过程详解
LAMP 架构在企业里用得非常广泛,目前很多电商公司.游戏公司.移动互联网公司大多都采用这种架构.LAMP指的是Linux.Apache.MySQL.PHP.下面记录了 LAMP 架构系统服务的搭建过 ...
- C语言文法推导
- [2017BUAA软工]第一次博客作业
一.一些疑问 看书看得比较慢,暂时只思考了以下几个问题,有些自问自答,不知道符合不符合要求…… [1] 第一章中书上提到了这样一个例子: “如果一架民用飞机上有需求,用户使用它的概率是百万分之一,你还 ...
- 第78天:jQuery事件总结(一)
jQuery事件总结(一) 现在就一点一点积累自己的知识体系,记录自己学到的和自己所理解的jQuery. JavaScript和HTML之间的交互式通过用户和浏览器操作页面时引发的事件机制来处理 ...
- CSUOJ 1141——第四届河南省程序设计大赛
题目的意思是给你一个机器人,初始的时候在某一个给定的路灯位置,机器人要把路边所有的路灯关掉,每个路灯都有一个距离和一个功率,求要把所有的路灯关掉最小的最终能耗是多少? 题目是一个很明显的区间DP.可以 ...
- 洛谷 P2664 树上游戏 解题报告
P2664 树上游戏 题目描述 \(\text{lrb}\)有一棵树,树的每个节点有个颜色.给一个长度为\(n\)的颜色序列,定义\(s(i,j)\) 为 \(i\) 到 \(j\) 的颜色数量.以及 ...
- Redis的Set无序集合命令
Set是集合,它是string类型的无序集合.set是通过hash table实现的,添加.删除和查找的复杂度都是0(1).对集合我们可以取并集.交集.差集.通过这些操作我们可以实现sns中的好友推荐 ...