RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 621921
Accepted
Vadim Prokopchuk
Vadim Prokopchuk
Asked:2020-02-01 04:56:22 +0000 UTC2020-02-01 04:56:22 +0000 UTC 2020-02-01 04:56:22 +0000 UTC

C#中如何正确比较字符串

  • 772

如何在 C# 中正确比较字符串:Equalsor ==?

string str1 = "s";
string str2 = "s";

Console.WriteLine("eq: " + str1.Equals(str2));
Console.WriteLine("==: " + (str1 == str2));

在这两种情况下,结果True都是尽管String是一个类并且运算符==必须比较引用。

IlDasm表明根据方法创建并比较了 2 个变量Equals,== (op_Equality)

  IL_0000:  nop
  IL_0001:  ldstr      "s"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "s"
  IL_000c:  stloc.1
  IL_000d:  ldstr      "eq: "
  IL_0012:  ldloc.0
  IL_0013:  ldloc.1
  IL_0014:  callvirt   instance bool [mscorlib]System.String::Equals(string)
  IL_0019:  box        [mscorlib]System.Boolean
  IL_001e:  call       string [mscorlib]System.String::Concat(object, object)
  IL_0023:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0028:  nop
  IL_0029:  ldstr      "==: "
  IL_002e:  ldloc.0
  IL_002f:  ldloc.1
  IL_0030:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_0035:  box        [mscorlib]System.Boolean
  IL_003a:  call       string [mscorlib]System.String::Concat(object, object)
c#
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    Umed
    2020-02-01T05:19:11Z2020-02-01T05:19:11Z

    ==在 C# 中,通过, 和比较字符串是正确的Equals。但是比较使用==.

    这是为什么?

    该方法Equals涉及比较引用类型对象的值,它被声明virtual为字符串,它被重载并按预期按值比较它们。在您的课程中,您必须为其提供自己的实现。否则,它的行为将与ReferenceEquals指向多个对象的引用一样false,即使它们的值相等。

    字符串运算符==提供了自己的实现,不同于所有其他引用类型对象的标准。如果被比较的引用是 type System.String,那么它会先比较这两个引用是否指向同一个对象,如果不是,它会比较这两个 type 的引用的System.String值。

    但需要注意一点,如果我们比较一个System.String( string) 类型的对象和一个System.Object指向字符串的 ( object ) 类型的对象,它们将按值进行比较。

    例子:

    string str = "str";
    object obj = "str";
    bool result = str.Equals(obj); 
    

    result将等于true,因为它将obj被强制转换为 type string,因为Equals我们在字符串( type 的对象)上调用了该方法string。

    但是如果我们比较一个System.Object指向字符串的类型(object)对象和一个System.String( )类型的对象string,它们将通过引用进行比较。

    例子:

    string str = "str";
    object obj = "str";
    bool result = obj.Equals(str);
    

    result将等于false,因为它将str被转换为 type object,因为Equals我们在 type 的对象上调用了该方法object。

    因此,在这种情况下,object转换为类型很重要string

    • 15
  2. user177221
    2020-02-01T05:35:40Z2020-02-01T05:35:40Z

    操作员==不需要仅比较引用。在 C# 中,运算符是可以被重写的,而且对于很多类型来说它自然被重写了。

    引用比较只是==未覆盖运算符的类型的默认行为。

    对于运算符被重新定义的类型,==并且很可能会被重新定义Equals,两种比较方法的结果很可能是相同的(如果不是,那么它的作者只是在设计类型时犯了一个错误)。

    这是来自参考源==的 String的实现:

    public static bool operator == (String a, String b) {
       return String.Equals(a, b);
    }
    
    public static bool Equals(String a, String b) {
        if ((Object)a==(Object)b) {
            return true;
        }
    
        if ((Object)a==null || (Object)b==null) {
            return false;
        }
    
        if (a.Length != b.Length)
            return false;
    
        return EqualsHelper(a, b);
    }
    

    这里是非静态 Equals 的实现:

    public override bool Equals(Object obj) {
        if (this == null)                        //this is necessary to guard against reverse-pinvokes and
            throw new NullReferenceException();  //other callers who do not use the callvirt instruction
    
        String str = obj as String;
        if (str == null)
            return false;
    
        if (Object.ReferenceEquals(this, obj))
            return true;
    
        if (this.Length != str.Length)
            return false;
    
        return EqualsHelper(this, str);
    }
    

    它们的不同之处仅在于对非静态性的小修正。两者都比较引用并检查大小写null != null,然后比较不平等的长度,然后才比较值。

    • 6
  3. DreamChild
    2020-02-01T05:39:27Z2020-02-01T05:39:27Z

    在 C# 中,== 运算符和 Equals 方法都为字符串重载,因为字符串通常需要按值而不是按引用进行比较。在 == 运算符的情况下,首先比较字符串指针,如果它们相等,则该方法返回 true。否则,将检查空操作数(如果其中至少有一个为空,则返回 false)。然后比较字符串长度。然后是字符串逐个字符的比较(即按值比较)。这是在本机代码中使用指针完成的(显然是出于性能原因),并且还使用了循环展开(显然是出于相同的原因,但在这种情况下这些细节并不重要)。如果你对细节感兴趣,你可以看这里

    • 5

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5