场景描述:

需要比对两个版本的对应对象是否完全一致(每个属性值一致),不一致的导出报表颜色标识,以便提醒后续使用报表人员。

实现思路:

对象重载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;
}
05-11 11:13