C# 关于c中字符串和对象相等的问题#

C# 关于c中字符串和对象相等的问题#,c#,equality,C#,Equality,我有以下问题 正如我们在C中所知道的# 字符串是引用类型 for string==运算符重载,以便按值执行比较 定义了以下变量 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); //

我有以下问题
正如我们在C中所知道的#

  • 字符串是引用类型
  • for string==运算符重载,以便按值执行比较
  • 定义了以下变量

    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为真s2==s3为假?s1和s2具有相同的类型-因此==运算符的行为应该相同。据我所知,s1和s2也在实习。(object.ReferenceEquals(s1,s2)返回True) 我错过了什么


    Thnaks in adavance

    为什么object==string不匹配
    string.operator==(string,string)
    ?因为其中一个参数不是字符串。。。因此,下一个匹配项是
    object.operator==
    ,它的行为不象字符串comaprison

    为什么字符串的内部版本(s1和s2)指向同一个对象?因为这就是interning所做的——确保同一个值作为一个对象只出现一次。特别是对同一模块中的所有字符串常量执行此操作(由编译器自行决定),因此s1和s2都指向该程序集中表示
    “foo”
    的相同且唯一的对象

    为什么非内部字符串(s3)与(s1/s2)不是同一个对象?因为它不一样-在运行时创建字符串不会插入字符串。

    ==运算符(以及C#中的任何运算符重载)是静态方法,因此调用的运算符由参数的静态类型选择。在
    (s2==s3)
    中,左侧操作数的静态类型是
    对象
    ,因此它不能与
    运算符==(字符串,字符串)
    方法的签名匹配


    试着用s2.Equals(s3)代替
    Equals
    是一个虚拟函数,因此在s2的动态类型上运行,即
    string
    。(这也是为什么
    s2.GetType()
    返回
    string
    )的原因。

    s1和s2的类型不同,但s1.GetType()和s2.GetType()返回相同的值系统。string比较基于它们的静态类型,而不是动态类型。感谢回复。但若s2有不同的类型,为什么s2.GetType()会为其返回字符串?调用object s2=“abc”?@lm时是否铸造。对象的类型(“字符串”)和变量的类型(“对象”)是两个不同且几乎不相关的东西(稍微受类型兼容性的限制)。根据编译时已知的变量/参数类型选择要在编译时执行的方法(包括
    operator==
    ),对于
    s2==s3
    ,该类型的变量/参数是“object==string”。请注意,如果强制在运行时选择方法,则会得到预期的结果-
    (动态)s2==s3
    返回
    true
    ,因为当运行时试图为“string”找到最佳匹配时,一些操作符=='string'确实会找到
    string。操作符==(string,string)
    对象更匹配。操作符==(object,object)