问题描述
我有以下问题
我们在C#中知道
- 字符串是引用类型
- 用于字符串==运算符的方法已重载,因此可以按值进行比较
定义了以下变量
string s1 = "foo";
object s2 = "foo";
string s3 = new String(new char[] {'f','o','o'});
bool b1 = (s1==s2); //true
bool b2 = (s2==s3); //false
bool b3 = (s1==s3); //true
bool b4 = (s1.equals(s3)); //true
对于所有变量s1,s2,s3的gettype()返回相同的val字符串 问题是:为什么s1 == s3是true s2 == s3 false? s1和s2具有相同的类型-因此==运算符的行为应相同。据我了解,S1和S2也实习。 (object.ReferenceEquals(s1,s2)返回True) 我想念什么?
高度重视
解决方法
为什么对象==字符串与string.operator == (string,string)
不匹配?因为参数之一不是字符串...所以下一个匹配的参数是object.operator ==
,它不表现为字符串同伴。
为什么字符串的intern版本(s1和s2)指向同一对象?因为这是实习生所做的-确保同一值作为一个对象仅出现一次。特别是对同一模块中的所有字符串常量都进行了此操作(由编译器自行决定),因此s1和s2均指向同一且仅表示该程序集中"foo"
的对象。
为什么非实习字符串(s3)与(s1 / s2)是不同的对象?因为它不一样,所以在运行时创建字符串不会实习字符串。
, ==运算符(以及C#中的任何运算符重载)都是静态方法,因此,被调用的运算符由参数的静态类型选择。在(s2==s3)
中,左操作数的静态类型为object
,因此它不能与operator ==(string,string)
方法的签名匹配。
改为尝试s2.Equals(s3)
。 Equals
是一个虚函数,因此对s2的动态类型进行操作,即string
。 (这也是s2.GetType()
返回string
的原因。)