C# Linux上.NET内核的字符编码错误

C# Linux上.NET内核的字符编码错误,c#,linux,character-encoding,.net-core,.net-core-2.1,C#,Linux,Character Encoding,.net Core,.net Core 2.1,这几天来一直让我焦头烂额,我终于把它归结为一个简单的、可复制的问题 我有一个NUnit测试项目,它是.NETCore2.1。它引用了一个库(我们称之为“核心”),它是.NET标准2.0 在我的测试项目中: [TestCase(true, false)] [TestCase(false, false)] [TestCase(false, true)] public void ShouldStartWith(bool useInternal, bool passStartsWith) { v

这几天来一直让我焦头烂额,我终于把它归结为一个简单的、可复制的问题

我有一个NUnit测试项目,它是.NETCore2.1。它引用了一个库(我们称之为“核心”),它是.NET标准2.0

在我的测试项目中:

[TestCase(true, false)]
[TestCase(false, false)]
[TestCase(false, true)]
public void ShouldStartWith(bool useInternal, bool passStartsWith)
{
    var result = useInternal ? StartsWithQ("¿Que?") : StringUtilities.StartsWithQ("¿Que?", passStartsWith ? "¿" : null);
    result.ShouldBeTrue();
}

public static bool StartsWithQ(string s)
{
    return _q.Any(q => s.StartsWith(q, StringComparison.InvariantCultureIgnoreCase));
}
StringUtilities
类的
Core
项目中:

public static bool StartsWithQ(string s, string startsWith = null)
{
    return startsWith == null
        ? _q.Any(q => s.StartsWith(q, StringComparison.InvariantCultureIgnoreCase))
        : s.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase);
}
两个类都定义了特殊字符列表:

private static readonly List<string> _q = new List<string>
{
    "¡",
    "¿"
};
私有静态只读列表_q=新列表
{
"¡",
"¿"
};
在Windows环境中,所有测试用例都通过。但是当相同的测试在Linux环境中运行时,测试用例
应该开始(False,False)
失败

这意味着,当测试项目中的所有内容都在运行时,字符串比较工作正常,即使您将特殊字符传递给
StringUtilities
方法,比较也工作正常。但是,与核心项目中编译的字符串相比,特殊字符不再等效


有人知道这是为什么吗?这是一个.NET错误吗?如何解决此问题?

源文件的编码很可能彼此不匹配和/或与编译器设置不匹配

例如:

包含
public void的源文件ShouldStartWith(bool useInternal,bool passStartWith)
可以使用utf-8进行编码,而包含列表的源文件则使用拉丁语-1(或类似的语言)进行编码

当我们玩这个游戏时:

  • 的utf-8表示形式为:
    0xC2 0xBF
  • 的拉丁文-1表示形式为:
    0xBF
因此,当编译器将源文件解释为Latin-1时,对于utf-8保存的文件,他将读取2个字节(根据Latin-1,还将读取2个字符),因此无法匹配字符串

正如在注释中已经指出的那样:克服这一问题的最佳方法是用编译器等待的编码方式对源文件进行编码


将操作系统作为错误源排除的另一种方法是:将编译的项目(dll-不要在其他操作系统上重新编译源代码)从一个操作系统复制到另一个操作系统,并执行代码。您应该在具有相同二进制编译器输出的两个操作系统上看到相同的行为。

在Linux上,单元测试和实现的文件类型都显示了什么?在我的机器上,它被报告为“代码>程序”:C+C++源,UTF-8 Unicode文本,测试通过。你能详细说明你建议的测试方法吗?就像任何文本文件一样,你必须正确地将字符编码传达给读取它的程序。您的源文件的编码是什么?您要告诉编译器什么?UTF-8将是一个很好的计划。(
file
是一个猜测编码的程序。它可能有用,也可能不有用,可以向您显示文件没有您认为的编码。需要一些解释。)@omajid
Test.dll:PE32+可执行文件(控制台)x86-64 Mono/.Net汇编,适用于MS Windows
Core.dll:PE32可执行文件(dll)(控制台)英特尔80386 Mono/.Net汇编,适用于MS Windows能否在源文件上运行该文件?包含倒置问号的所有文件。另一件需要考虑的事情是:您能为这些非ascii字符使用unicode转义码(
\udddd
)吗?这有助于测试结果吗?.Net使用UTF-16表示字符和字符串。另请参见MSDN。如果使用UTF-8或Latin-1时未进行显式转换,则情况是横向的。您会混淆源文件中的编码和运行时使用的编码。