比较时,Equals() 方法无法识别 similar/same 个字符

Equals() method not recognizing similar/same characters when comparing

为什么比较字符 .Equals 总是 returns 错误?

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

总的来说,我正在尝试编写英语 - 摩尔斯电码 t运行slator。我 运行 在比较上面显示的 char 值时遇到了问题。我从 foreach 开始分析来自 ReadLine() 输入的所有字符,通过使用 WriteLine() 方法,所有字符的 t运行 都很好,但是当尝试使用 .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来测试它是否识别和运行正确的输出,但最后,当我将"sample"写到[=16时=],它给了我:

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

对于字符比较,您必须使用单引号 ' 字符而不是 " 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 + "'");
  }
}

当你这样做时:

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

结果 (isEqual) 将始终为假,因为它正在比较 stringchar。这将 return 为真:

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") 

它不会编译。它会告诉你你正在比较一个 char 和一个 string,然后它更容易,因为而不是 运行 程序并寻找错误它根本不会编译它会准确地告诉你问题出在哪里。


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

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;
    }
}

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

MorseCodeConverter.Convert(input);

得到结果,然后可以打印到console.a

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

重要的是要记住,虽然 char and string 关键字在查看印刷值时看起来让人联想到彼此,但您应该注意它们并不是以完全相同的方式容纳的。

检查字符串时可以使用:

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

但是,以上不适用于 char。表面上的 difference between chars (value types) and strings (reference types) 是访问的使用 - 单引号(撇号)与引号。

要比较 char 你可以这样做:

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

然而,在与您的具体情况相关的一点上,摩尔斯电码只会要求您使用单一大小写的字母表,因此当您尝试与 'A''a' 进行比较时,您可以调用input.ToLower() 将您的 var(字符串)缩减为全部小写,因此您无需同时满足大写和小写字母。

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

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

本可以让您比较字符,但这是一种不好的做法,因为它可能会导致以相同的方式对字符串进行惰性比较,并且:

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

是一种非代表性的比较方法,用于比较字符串,因为它计算的是引用而不是直接值,请参阅 here

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

这就是为什么 returns 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);