如何遍历类中的 SortedList

Posted

技术标签:

【中文标题】如何遍历类中的 SortedList【英文标题】:How to iterate through a SortedList within a class 【发布时间】:2017-09-10 09:53:46 【问题描述】:

生日,

在下面的简单代码示例中,我使用一个简单的列表在一个Employees 对象中存储多个Employee 对象。我想将 List 更改为使用 Employee.Number 作为 TKey 的 SortedList,这样 foreach 循环将始终按 Employee.Number 升序打印员工,以便Employees 类中的 Item 方法将检索一个Employee 通过它的 Employee.Number 而不是它在 List 中的索引位置。

我认为这将是微不足道的,但我似乎无法正确地使用语法来使 SortedList 从Employees 类之外可迭代......?因此,如果有人可以修改我的示例代码来给我指路,我将不胜感激。

感谢您的帮助,

马丁。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1

class Program
    
    static void Main(string[] args)
    
      clsEmployees Employees = new clsEmployees();

      Employees.Add(new clsEmployee(3, "Fred"));
      Employees.Add(new clsEmployee(5, "Jane"));
      Employees.Add(new clsEmployee(2, "Bob"));
      Employees.Add(new clsEmployee(1, "Sarah"));

      foreach (clsEmployee Employee in Employees)
      
          Console.WriteLine("0  1", Employee.Number, Employee.Name);
      

      Console.ReadLine();
    
  

public class clsEmployee

    public int Number;
    public string Name;

    public clsEmployee(int SetNumber, string SetName)
    
        Number = SetNumber;
        Name = SetName;
    


public class clsEmployees : IEnumerable<clsEmployee>

    private List<clsEmployee> EmployeeList;

    public clsEmployees()                              EmployeeList = new List<clsEmployee>(); 

    IEnumerator IEnumerable.GetEnumerator()            return GetEnumerator(); 
    public IEnumerator<clsEmployee> GetEnumerator()    return EmployeeList.GetEnumerator(); 

    public void Add(clsEmployee NewEmployee)           EmployeeList.Add(NewEmployee); 

    public clsEmployee Item(int Index)                 return EmployeeList[Index]; 
    

【问题讨论】:

【参考方案1】:

您可以做的不是尝试创建新类型,而是在每次要迭代列表时使用 LINQ 对列表进行排序

  clsEmployees Employees = new clsEmployees();
  Employees.Add(new clsEmployee(3, "Fred"));
  Employees.Add(new clsEmployee(5, "Jane"));
  Employees.Add(new clsEmployee(2, "Bob"));
  Employees.Add(new clsEmployee(1, "Sarah"));

  var sortedList = Employees.OrderBy(t => t.Number);
  foreach (var employee in sortedList)
  
      Console.WriteLine("0  1", Employee.Number, Employee.Name);
  

  Console.ReadLine();

PS:您似乎对 C# 的语法约定有些困惑。我建议你看看 MSDN 的编码约定:https://msdn.microsoft.com/en-us/library/ff926074.aspx

【讨论】:

@Authur Attout 谢谢。我有点意识到这种可能性,但我想使用 SortedList 如果有兴趣,另请参阅我的 cmets 到 Peter Duniho 的解决方案。再次感谢马丁。【参考方案2】:

从您的问题中不清楚您具体遇到了什么问题。您没有显示任何尝试使用 SortedList&lt;TKey, TValue&gt; 的代码,因此无法确切知道您做错了什么。

以下是我的处理方法:

public class clsEmployees : IEnumerable<clsEmployee>

    private SortedList<int, clsEmployee> EmployeeList;

    public clsEmployees()
    
        EmployeeList = new SortedList<int, clsEmployee>();
    

    IEnumerator IEnumerable.GetEnumerator()
    
        return GetEnumerator();
    

    public IEnumerator<clsEmployee> GetEnumerator()
    
        return EmployeeList.Values.GetEnumerator();
    

    public void Add(clsEmployee NewEmployee)
    
        EmployeeList.Add(NewEmployee.Number, NewEmployee);
    

    public clsEmployee Item(int Index)
    
        return EmployeeList[Index];
    

注意事项:

SortedList&lt;TKey, TValue&gt; 类型需要两个类型参数。第一个是键类型,第二个是值类型。您的键是Number 属性,因此必须是int 类型,而值是clsEmployee 对象本身,因此必须是该类型。 枚举时,您只需要集合中的值,而不是使用整个集合枚举的键/值对。所以你应该返回Values 属性的GetEnumerator() 结果。 添加新对象时,需要指定键值。因此,NewEmployee.Number SortedList&lt;TKey, TValue&gt; 类型的索引器可以按照您的意愿工作,因此无需更改任何内容。 :) 我没有更改您的任何命名。但我同意您会从学习和遵循 Microsoft 的命名约定中受益。

这看起来很像家庭作业。如果这是作业的一部分,您可能仍然应该与老师一起回顾您的不确定性和困难,以便他们可以确保您已经学习了他们希望您学习的概念。

【讨论】:

非常感谢,您的回答恰到好处。这是我坚持的第二点 - return EmployeeList.VALUES.GetEnumerator(); - 我只是看不到... .'s the 非常感谢,您的回答恰到好处。这是我坚持的第二点 - return EmployeeList.VALUES.GetEnumerator(); - 我只是看不到... 至于你是否质疑它的家庭作业,让我向你保证它不是(嗯,它是在家工作,但不是你的意思的家庭作业)事实上我是一个我 50 多岁的电子硬件工程师。近一百万年前,我开始学习 Microsoft Level II Basic 编程。很久以后,我做了很多 VB 3、5 和 6。现在主要是嵌入式系统上的 C 和 C++,但偶尔我会涉足一点 C#... 所以我的代码示例故意是一个非常简化的示例,足以说明我想要做什么。我没有展示我的非工作简化示例,因为我对它太困惑(或太尴尬)了。无论如何,真正的类,即“clsComponentRequestRecord”,大约有 400 行并且还在增长。是的,我的命名约定可以追溯到 VB - 很难教老狗新技巧......再次感谢 Martin。 对这个答案要非常非常小心——特别是Item(int Index) 方法。它返回EmployeeList[Index]。由于您将 EmployeeList 更改为 SortedList&lt;int, clsEmployee&gt; 类型,因此您将返回具有匹配 TKey 的项目,不是列表中的第 n 个项目。例如,根据您的示例数据,Employees[1] 将返回 Sarah。 Employees[0] 会抛出异常。这可能是有意的……或者您可能需要返回并修复一堆代码。有关Item(int Index) 的其他实现,请参阅下面的答案 @Yeager:来自原始问题:“因此,Employees 类中的 Item 方法将通过 Employee.Number 而不是索引位置检索 Employee”。很明显,您“警告”的事情正是 OP 想要的事情。鉴于上面发布的问题,您的回答完全不正确。

以上是关于如何遍历类中的 SortedList的主要内容,如果未能解决你的问题,请参考以下文章

java中遍历类中的属性

利用运行时遍历一个类中的成员变量。

Angular 类中的数组数组

如何在类中移动这个方法装饰器模式?

Java8中Stream类中的forEach是抽象方法,为啥在调用的时候不用重写该方法就能实现遍历?

设计模式之迭代器模式