Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “为什么?”-减去;按“排序”;“你好”;而不是在它之前?_C#_.net_Sorting - Fatal编程技术网

C# “为什么?”-减去;按“排序”;“你好”;而不是在它之前?

C# “为什么?”-减去;按“排序”;“你好”;而不是在它之前?,c#,.net,sorting,C#,.net,Sorting,我看到一些非常奇怪的排序行为,使用CaseInsensitiveComparer.default不变量。以前导连字符“-”开头的单词最终被排序,就像连字符不在那里一样,而不是排序在实际字母前面,这是其他标点符号的情况 因此,给定{“hello”、“.net”、“-less”},我最终得到的是{.net”、“hello”、“-less”},而不是预期的{“-less”、“.net”、“hello”} 或者,作为测试用例使用: [TestMethod] public void TestMethod1

我看到一些非常奇怪的排序行为,使用CaseInsensitiveComparer.default不变量。以前导连字符“-”开头的单词最终被排序,就像连字符不在那里一样,而不是排序在实际字母前面,这是其他标点符号的情况

因此,给定{“hello”、“.net”、“-less”},我最终得到的是{.net”、“hello”、“-less”},而不是预期的{“-less”、“.net”、“hello”}

或者,作为测试用例使用:

[TestMethod]
public void TestMethod1()
{
    var rg = new String[] { 
        "x", "z", "y", "-less", ".net", "- more", "a", "b"
    };

    Array.Sort(rg, CaseInsensitiveComparer.DefaultInvariant);

    Assert.AreEqual(
        "- more,-less,.net,a,b,x,y,z", 
        String.Join(",", rg)
    );
}
。。。失败的原因如下:

Assert.AreEqual failed. 
Expected:<- more,-less,.net,a,b,x,y,z>. 
Actual:  <- more,.net,a,b,-less,x,y,z>.

我的猜测是,为了排序,一封信前面的破折号被忽略了。当你对一系列单词进行排序时,你希望“国际”和“国际”相邻,不是吗?另一方面,破折号本身被认为是重要的

比较过程使用CultureInfo.InvariantCulture来确定排序顺序和大小写规则。根据区域性的不同,字符串比较可能会有不同的结果。有关特定于区域性的比较的更多信息,请参阅System.Globalization命名空间和编码与本地化。

有趣的是:

单词排序对某些非字母数字Unicode字符可能具有指定的特殊权重的字符串执行区域性敏感比较。例如,连字符(-)可能具有非常小的权重,以便“coop”和“co-op”在排序列表中彼此相邻。


排序顺序取决于区域性,因此不能假设字符将按ASCII顺序排序


在您的示例中,“h”(U+0048)在“dash”(U+2013)之前,因此“hello”将出现在“-less”之前。“,”(U+002E)在两者之前,因此“.net”首先出现。

要按需要对字符串进行排序,必须创建一个比较器类,使用。这个类允许您指定各种比较方法,最符合您需要的方法是OrdinalIgnoreCase

从MSDN:

忽略的搜索值

比较操作,例如 由索引执行,或 LastIndexOf方法,可以生成 如果值为,则会出现意外结果 搜索被忽略。搜寻 如果值为空,则忽略该值 字符串(“”),一个字符或字符串 由具有代码的字符组成 计划中未考虑的要点 比较操作 选项,或带有代码点的值 没有语言意义。 如果索引的搜索值为 方法是空字符串,例如 例如,返回值为零


如果可能,应用程序 应该使用字符串比较方法 将CompareOptions值接受为 指定比较的类型 预期。一般来说, 面向用户的比较是最好的 通过使用语言来服务 选项(使用当前区域性), 而安全性比较应该 指定Ordinal或OrdinalIgnoreCase。指定Ordinal或OrdinalIgnoreCase

我已经修改了您的测试用例,并且该测试用例正确执行:

public class MyComparer:Comparer<string>
{
    private readonly CompareInfo compareInfo;

    public MyComparer()
    {
        compareInfo = CompareInfo.GetCompareInfo(CultureInfo.InvariantCulture.Name);
    }

    public override int Compare(string x, string y)
    {
        return compareInfo.Compare(x, y, CompareOptions.OrdinalIgnoreCase);
    }
}

public class Class1
{
    [Test]
    public void TestMethod1()
    {
        var rg = new String[] { 
    "x", "z", "y", "-less", ".net", "- more", "a", "b"
};

        Array.Sort(rg, new MyComparer());

        Assert.AreEqual(
            "- more,-less,.net,a,b,x,y,z",
            String.Join(",", rg)
        );


    }
}
公共类MyComparer:Comparer
{
私有只读CompareInfo CompareInfo;
公共MyComparer()
{
compareInfo=compareInfo.GetCompareInfo(CultureInfo.InvariantCulture.Name);
}
公共覆盖整型比较(字符串x、字符串y)
{
返回compareInfo.Compare(x,y,CompareOptions.OrdinalIgnoreCase);
}
}
公共班级1
{
[测试]
公共void TestMethod1()
{
var rg=新字符串[]{
“x”,“z”,“y”,“少”,“净”,“多”,“a”,“b”
};
Sort(rg,newmycomparer());
断言你是平等的(
“-more,-less,.net,a,b,x,y,z”,
String.Join(“,”,rg)
);
}
}

不是真的-我希望(也期望)根据嵌入的非alpha字符在ASCII字符集中的位置对其进行排序。你是说根据这个比较器,“国际”和“国际”是一样的吗?那么OP可以解决如下困惑?字符串排序还执行区域性敏感比较。它与单词排序类似,只是没有特殊情况,并且所有非字母数字符号都位于所有字母数字Unicode字符之前。通过调用CompareInfo,可以使用字符串排序规则对两个字符串进行比较。具有选项参数th的Compare方法重载at提供了CompareOptions.StringSort的值。请注意,这是.NET Framework提供的使用字符串排序规则比较两个字符串的唯一方法。“+1,回答得好。通过思考各种各样的破折号来爆炸你的大脑,你键盘上的破折号总是错误的:如果每个问题都可以表示为一个单元测试,那么在没有空格的情况下,它可能被认为是类似于一个负号。我不知道“.”,但它看起来像是StringComparer.InvariantCulture在进行比较之前吃掉了所有的破折号“-”。错误的解释。尝试对“aa”、“-bb”和“cc”进行排序,您会发现unicode顺序在这里并不重要。比较器更有可能“吃掉”引导点和破折号。
public class MyComparer:Comparer<string>
{
    private readonly CompareInfo compareInfo;

    public MyComparer()
    {
        compareInfo = CompareInfo.GetCompareInfo(CultureInfo.InvariantCulture.Name);
    }

    public override int Compare(string x, string y)
    {
        return compareInfo.Compare(x, y, CompareOptions.OrdinalIgnoreCase);
    }
}

public class Class1
{
    [Test]
    public void TestMethod1()
    {
        var rg = new String[] { 
    "x", "z", "y", "-less", ".net", "- more", "a", "b"
};

        Array.Sort(rg, new MyComparer());

        Assert.AreEqual(
            "- more,-less,.net,a,b,x,y,z",
            String.Join(",", rg)
        );


    }
}