C# 排序/排序 DateTimeOffset

C# Sort / Order DateTimeOffset

根据我在这里回答的问题(C# Sort / Order a textBox with given Values),我还有一个问题。 (感谢 JohnG) 我现在已经编写了我的代码来使用系统给我的值。 我现在不知道为什么,但是 orderby 子句被完全忽略了。 OrderBy 和 OrderByDescending 的结果是相同的,没有任何排序/排序。

这里是手工创建值的代码:

string[] test1 = { "2021-12-08", "2020-04-12", "2021-06-15", "2022-11-28", "2019-01-12" };
IEnumerable<string> query1 = test1.OrderBy(i => i.ToString());
foreach (string r in query1)
{
    textBox3.Text += r.ToString() + "\r\n";
}

结果:

2019-01-12
2020-04-12
2021-06-15
2021-12-08
2022-11-28

这是问题代码

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_QuickFixEngineering");
var managementObjectCollection = searcher.Get();

foreach (ManagementObject queryObj in searcher.Get())
{
    string stringDate = queryObj["InstalledOn"].ToString();
    string format = "M/d/yyyy";
    CultureInfo provider = CultureInfo.InvariantCulture;
    DateTimeOffset result = new DateTimeOffset();
    result = DateTimeOffset.ParseExact(stringDate, format, provider, DateTimeStyles.AssumeUniversal);
    systemLastWindowsUpdate = result.ToString("yyyy-MM-dd");

    string[] test = { systemLastWindowsUpdate };
    IEnumerable<string> query = test.OrderByDescending(g => g.ToString());

    //MessageBox.Show(query.ToString()); // Gives System.Linq.OrderedEnumerable`2[System.String,System.String]
    foreach (string t in query)
    {
        textBox2.Text += t.ToString() + "\r\n";
    }
}

结果:

2021-07-19
2020-09-27
2020-09-27
2020-09-27
2021-03-01
2020-11-17
2020-11-17
2021-03-15
2020-12-14
2021-01-18
2021-07-19
2021-07-19

希望大家有想法。我不需要完美高效的代码。我正在学习,工作代码绝对没问题。

您正在将 OrderByDescending 应用于包含单个元素 string[] test = { systemLastWindowsUpdate }; 的数组。

相反,将格式化的日期附加到列表中,然后对列表进行排序。排序必须在 foreach 循环之后进行,即在处理完所有日期之后,对整个日期列表进行排序:

var searcher = new ManagementObjectSearcher(
    "SELECT * FROM Win32_QuickFixEngineering");
var dates = new List<string>();
foreach (ManagementObject queryObj in searcher.Get())
{
    string stringDate = queryObj["InstalledOn"].ToString();
    string format = "M/d/yyyy";
    CultureInfo provider = CultureInfo.InvariantCulture;
    DateTimeOffset result = new DateTimeOffset();
    result = DateTimeOffset.ParseExact(
        stringDate, format, provider, DateTimeStyles.AssumeUniversal);
    systemLastWindowsUpdate = result.ToString("yyyy-MM-dd");

    dates.Add(systemLastWindowsUpdate);
}

// Now the list contains all the dates, and you can sort it:
IEnumerable<string> query = dates.OrderByDescending(s => s);
textBox2.Text = String.Join("\r\n", query);

此外,不要在循环中将文本重复附加到 TextBox,因为这会涉及开销。 TextBox 可能每次都会引发事件,从而使循环非常缓慢。在将最终结果分配给 TextBox 一次之前,我使用 String.Join 创建一个字符串。


你也可以使用Language Integrated Query (LINQ)来一次转换和排序,没有循环也没有列表:

var searcher = new ManagementObjectSearcher(
    "SELECT * FROM Win32_QuickFixEngineering");

string format = "M/d/yyyy";
CultureInfo provider = CultureInfo.InvariantCulture;

var query = searcher.Get()
    .Select(queryObj => DateTimeOffset.ParseExact(
        queryObj["InstalledOn"].ToString(),
        format, provider, DateTimeStyles.AssumeUniversal
     ).ToString("yyyy-MM-dd"))
    .OrderByDescending(s => s);

textBox2.Text = String.Join("\r\n", query);

另请参阅:Query Syntax and Method Syntax in LINQ (C#)

试试这个:

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_QuickFixEngineering");
var managementObjectCollection = searcher.Get();
var sorted = managementObjectCollection.
     Select(o => DateTimeOffset.ParseExact(o["InstalledOn"], "M/d/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal)).
     OrderByDescending(o => o);

textBox2.Text += string.Join("\n", sorted.Select(d => d.ToString("yyyy-MM-dd"));

问题是 test 数组被重建为在循环的每次迭代中仅包含一个元素。解决此问题后,我们可以通过让日期对象进行排序来进一步改进事情,这往往比对字符串进行排序更快,并在将最终字符串添加到文本框之前在内存中构建最终字符串。除了提高性能之外,这些更改还减少了我们需要的代码量。