序:
昨天技术群中的一个小伙伴发了几个字符串以及值类型比较的面试题,没想到我们的答案不尽人意。。。下面是截图以及答案,看看与各位看官的答案是否相同。



0x00:
查看了几篇前辈写的博客后也有了自己的一些小总结,如有错误请大家指教出来,不胜感激!下面是参考资料的传送门。
http://new-fighter.iteye.com/blog/1634800
0x01:
众所周知Java中的String有两种声明方式,1:String str1 = "abc";2:String str2 = new String("abc");这两种存在很大的差异。这里不说,因为此篇的主角是C#。而C#中的string作为引用类型只有一中方式,也就是上述的方式一。在此无论使用“==”还是“Equals”只要是string的字面量相同则比较结果就为ture。这个没什么好说的,下面说一下非string的其他引用类型。
private class ObjectA
{
public string cName = "";
public int iAge = 0;
}
ObjectA oa1 = new ObjectA();
ObjectA oa2 = new ObjectA();
oa1.cName = "Clown";
oa1.iAge = 18;
oa2.cName = "Clown";
oa2.iAge = 18;
bool b01 = oa1.Equals(oa2);
bool b02 = oa1 == oa2;
object o1 = 1;
object o2 = 1;
bool b5 = (o1 == o2); // false
bool b6 = (o1.Equals(o2)); // false
以上的代码中声明了一个ObjectA类,并在下方实例化了两此此类,给此类的属性赋予了相同的值,通过“==” 与“Equals”比较得到的结果均为false,由此可以推断出除string外的引用类型两者比较的都是引用地址。
0x02:
等等,先不要着急关闭浏览器 。引用类型中还有一个特殊的,那就是匿名类。所以上面的0x01中的总结是有BUG的。我们还是先看一下代码,如下:
var a1 = new { name = "123", age = 12 };
var a2 = new { name = "123", age = 12 };
var a3 = new { age = 12, name = "123" };
int i1 = a1.GetHashCode(); // -1902033810
int i2 = a2.GetHashCode(); // -1902033810
int i3 = a3.GetHashCode(); // -843859346
bool b4 = a1.Equals(a2); // true
bool b5 = a1.Equals(a3); // false
bool b6 = a1 == a2; // false
//bool b7 = (a1 == a3); // 如果这面写直接就会爆语法错误的
上述中声明了a1,a2,a3三个匿名,其中a1,a2属性相同,值相同,属性顺序相同。而a3与两者比较属性相同,值相同,属性属性不相同。则得出的Hash值与两者也有差异。
0x03:
以上实验结果可以粗略总结为:C#中string(引用类型)通过“==”与“Equals”比较都是对字面量进行比较的,除去string与匿名类外的其他引用类型“==”与“Equals”比较的都是引用地址。而匿名类是通过“==”进行值比较,“Equals”是对引用地址的比较。且还得出匿名类顺序不同则AnonyType是不同的类型。
而序中提到的short.Equals(int)的比较是对我最为困惑的,现在可以根据以上结果分析,short.Equals中形参是Object类型,而引用类型通过“Equals”比较的是引用地址而非字面值。但int.Equals(int),形参为值类型的int,值类型存储在栈上比较的是字面值。故返回true而前者返回false。
|