比较时,Equals()方法无法识别相似/相同字符

时间:2019-05-02 21:13:11

标签: c# comparison equals

为什么将字符与.Equals进行比较总是返回false?

char letter = 'a';
Console.WriteLine(letter.Equals("a")); // false

总体而言,我正在尝试编写英语-莫尔斯电码翻译器。我在比较上面显示的char值时遇到问题。我从foreach开始,使用ReadLine()方法分析了WriteLine()输入中的所有字符,所有字符都被很好地调换了,但是当尝试使用.Equals比较它们时()方法,无论我做什么,在尝试比较字符时它总是输出false。

我已经成功地将.Equals()方法与其他字符串一起使用,但是它似乎不适用于我的字符。

using System;
public class MorseCode {
  public static void Main (string[] args) {
    Console.WriteLine ("Hello, write anything to convert it to morse code!");
    var input = Console.ReadLine();
    foreach (char letter in input) {
      if(letter.Equals("a")) {
        Console.WriteLine("Its A - live");
      }
      Console.WriteLine(letter);
    }
    var morseTranslation = "";
    foreach (char letter in input) {
      if(letter.Equals("a")) {
       morseTranslation += ". _ - ";
      }
      if(letter.Equals("b")) {
       morseTranslation += "_ . . . - ";
      }
      if(letter.Equals("c")) {
       morseTranslation += "_ . _ . - ";
      }
      ...
      }
    }
    Console.WriteLine("In morse code, " + input + " is '"morseTranslation + "'");
  }
}

在一开始,我编写了foreach来测试它是否识别并运行正确的输出,但是最后,当我在ReadLine()中编写“ sample”时,它给了我:< / p>

Hello, write anything to convert it to morse code!
sample
s
a
m
p
l
e

4 个答案:

答案 0 :(得分:3)

执行此操作时:

var c = 'x';
var isEqual = c.Equals("x");

结果(isEqual)始终为假,因为它会将stringchar进行比较。这将返回true:

var isEqual = c.Equals('x');

区别在于"x"string文字,而'x'char文字。

造成这种混乱的部分原因是,当您使用对象的Equals方法时,它允许您将任何类型与任何其他类型进行比较。因此,您可以这样做:

var x = 0;
var y = "y";
var isEqual = x.Equals(y);

...,即使intstring之间的比较不起作用,编译器也会允许它。它将向您发出此警告:

intchar等值类型与相同类型的其他值进行比较时,我们通常使用==,例如

if (someChar == someOtherChar)

然后,如果您尝试执行此操作:

if(someChar == "a") 

它不会编译。它会告诉您,您正在将charstring进行比较,这很容易,因为与其运行程序并寻找错误,它根本不会编译,而是告诉您您正是问题所在。


只是为了好玩,这是另一个实现。

public static class MorseCodeConverter
{
    private static readonly Dictionary<char, string> Codes 
        = CreateMorseCodeDictionary();

    public static string Convert(string input)
    {
        var lowerCase = input.ToLower();
        var result = new StringBuilder();
        foreach (var character in input)
        {
            if (Codes.ContainsKey(character))
                result.Append(Codes[character]);
        }
        return result.ToString();
    }

    static Dictionary<char, string> CreateMorseCodeDictionary()
    {
        var result = new Dictionary<char, string>();
        result.Add('a', ". _ - ");
        result.Add('b', "_ . . . - ");
        // add all the rest
        return result;
    }
}

一个区别是它本身就是一个类,没有控制台应用程序。然后,您可以在控制台应用程序中使用它。从键盘上读取输入,然后调用

MorseCodeConverter.Convert(input);

获取结果,然后可以将其打印到控制台。a

将所有字符放在字典中意味着无需重复if/then,而只需检查每个字符是否在字典中即可。

答案 1 :(得分:2)

重要的是要记住,虽然charstring关键字在查看打印值时看起来彼此非常遥远,但是您应该注意,它们的容纳方式并不完全相同。

当您检查字符串时,可以使用:

string s = "A";
if(s.Equals("A"))
{
    //Do Something
}

但是,以上内容不适用于char。表面上differencechars)和字符串(value types)之间的reference types是访问权限的使用-单引号(撇号)与引号。

要比较char,可以执行以下操作:

char s = 'A';
if(s.Equals('A'))
{
    //Do Something
}

但是,在与您的特定案例有关的一点上,摩尔斯电码仅要求您使用单个大小写字母,因此,当您尝试与'A''a'进行比较时,可以致电{{ 1}},将input.ToLower()(字符串)减少为所有小写字母,因此您无需同时满足大写和小写字母的需要。

很高兴您知道字符串比较,并且没有像这样使用direct value comparisson

var

本来可以比较char的,但是这是一种不好的做法,因为它可能以相同的方式导致字符串的惰性比较:

if (letter == 'a')
{
    Console.WriteLine("Its A - live");
}

出于比较字符串的目的,这是一种非代表性的比较方法,因为它评估引用而不是直接值,请参见here

答案 2 :(得分:1)

在C#中,您可以使用==运算符来比较整数之类的字符串。 Equals是从object类继承的方法,通常实现会进行一些类型检查。 char letter是字符(显然),而"a"是单个字母string

这就是为什么它返回false的原因。

您可以使用if (letter.Equals('a')) { ... },或更简单的if (letter == 'a') { ... }

switch (letter) { case 'a': ...; break; ... }更简单。

使用LINQ,或者对于初学者来说更优雅但又太高级的东西:

var validCharacters = "ABCDE...";
var codes = new string[] {
".-", "-...", "-.-.", "-..", ".", ...
};
var codes = input.ToUpper() // make uppercase
  .ToCharArray() // explode string into single characters
  .Select(validCharaters.IndexOf) // foreach element (i. e. character), get the result of "validCharacters.IndexOf",
                                  // which equals the index of the morse code in the array "codes"
  .Where(i => i > -1) // only take the indexes of characters that were found in "validCharacters"
  .Select(i => codes[i]); 

// retrieve the matching entry from "codes" by index
// "codes" is now an IEnumerable<string>, a structure saying
// "I am a list of strings over which you can iterate,
//  and I know how to generate the elements as you request them."
// Now concatenate all single codes to one long result string
var result = string.Join(" ", codes);

答案 3 :(得分:0)

对于字符比较,您必须使用单引号'字符而不是'this。 顺便说一下,由于您在第一个foreach循环中将所有字母都写在新行中,因此它以降序顺序编写样本。因此,以下代码将为您工作:

using System;
public class MorseCode {
  public static void Main (string[] args) {
    Console.WriteLine ("Hello, write anything to convert it to morse code!");
    var input = Console.ReadLine();
    /*foreach (char letter in input) {
      if(letter.Equals("a")) {
        Console.WriteLine("Its A - live");
      }
      Console.WriteLine(letter);
    }*/
    var morseTranslation = "";
    foreach (char letter in input) {
      if(letter.Equals('a')) {
       morseTranslation += ". _ - ";
      }
      if(letter.Equals('b')) {
       morseTranslation += "_ . . . - ";
      }
      if(letter.Equals('c')) {
       morseTranslation += "_ . _ . - ";
      }
      ...
      }
    }
    Console.WriteLine("In morse code, " + input + " is '"morseTranslation + "'");
  }
}