C# IComparer<;T>;列表排序的实现问题<;T>;
我在创建自己的列表结构时遇到了一些问题。我正在尝试创建一个名为SortedList的列表结构。其目标是在添加新项目后立即对其项目进行排序。这个列表在我使用它的项目中不会太大(最多50-100个项目)。然而,我通过添加一个简单的类Employee项进行测试,该类具有Name属性。我想让这个分类列表按员工的名字分类 这是我的尝试 雇员阶级C# IComparer<;T>;列表排序的实现问题<;T>;,c#,C#,我在创建自己的列表结构时遇到了一些问题。我正在尝试创建一个名为SortedList的列表结构。其目标是在添加新项目后立即对其项目进行排序。这个列表在我使用它的项目中不会太大(最多50-100个项目)。然而,我通过添加一个简单的类Employee项进行测试,该类具有Name属性。我想让这个分类列表按员工的名字分类 这是我的尝试 雇员阶级 public class Employee : IComparer<Employee> { public string Name { get;
public class Employee : IComparer<Employee>
{
public string Name { get; set; }
public Employee()
{
}
public int Compare(Employee x, Employee y)
{
return string.Compare(x.Name, y.Name,true);
}
}
我做错了什么?请告知。谢谢。你要问的具体问题就像问为什么一样
int f(object o) { return o is int ? o : 0; }
无法编译。即使您在运行时检查了o
是否有typeint
,但在编译时它仍然有typeobject
,这意味着它不能用作返回值。你需要一个演员来让它发挥作用:
int f(object o) { return o is int ? (int)o : 0; }
这同样适用于您的代码
但还有更根本的问题。您的
员工
不应实施IComparer
。它应该是实现的,它不是指定一个Employee
对象知道如何比较另外两个Employee
对象,而是指定它知道如何将自己与另一个Employee
对象进行比较。当您这样做时,您应该能够调用list.Sort()
完全不检查类型。列表。排序方法可以以多种方式工作
此方法使用类型T的默认比较器comparer.default来确定列表元素的顺序。默认属性检查类型T是否实现IComparable泛型接口,并使用该实现(如果可用)。如果不是,Comparer.Default将检查类型T是否实现IComparable接口。如果类型T未实现任何一个接口,则Comparer.Default会抛出InvalidOperationException
因此,通过进行以下更改,它将开始为您工作
public class Employee : IComparable<Employee> {
public string Name { get; set; }
public Employee() {
}
public int CompareTo(Employee other) {
return string.Compare(Name, other.Name, true);
}
}
非常感谢。但是intellisense of Sort()告诉我传递一些实现IComparer的东西。这就是为什么我认为如果Employee类实现了IComparer,那么它将起作用,因为我可以将一个新的Employee()作为参数传递给List的排序方法。@user5078178是的,如果您想传递一个比较器,您确实需要在某个类上实现
IComparer
。通常,这将在自定义的EmployeeComparer
类上完成,而不是直接在Employee
上完成。如果你采取这种方法,那也行,只要你像我提到的那样包括演员。但是在提到实现IComparable
之后,我还提到调用list.Sort()代码>,即不需要比较器的重载。:)好的,这是有道理的。所以我应该创建一个名为EmployeeComparer的新类:IComparer。谢谢,谢谢,维克拉姆。用于解释和解决方案。有没有办法使用IComparer使其正常工作?只是好奇而已。@Vikram-谢谢你展示了实现IComparer的另一种方法。我现在明白了,您已经使用了一个演员阵容(正如hvd所暗示的)。再次感谢您的详细回复。非常有帮助@user5078178您需要强制转换,因为排序
函数的参数是列表
,而不是列表
。即使在调用之前键入check,编译器也无法知道此运行时信息。列表中没有任何内容可确保唯一性。这是我在这里要做的另一件事。但我的问题是关于分类。它可以在我不告诉它如何排序的情况下对值类型进行排序。有些人建议使用Linq。但是Linq的排序方法返回另一个列表。事实上,我希望每次添加/删除这个列表时都能对其进行排序。你说得对。我忽略了“自动排序”部分。
list.Sort(EmployeeComparer);
int f(object o) { return o is int ? o : 0; }
int f(object o) { return o is int ? (int)o : 0; }
public class Employee : IComparable<Employee> {
public string Name { get; set; }
public Employee() {
}
public int CompareTo(Employee other) {
return string.Compare(Name, other.Name, true);
}
}
private static void Sort(List<T> list) {
var type = typeof(T);
list.Sort();
}
class Program {
static void Main() {
SortedList<Employee> list = new SortedList<Employee>();
list.Insert(new Employee() { Name = "Zach" });
list.Insert(new Employee() { Name = "Neil" });
list.Insert(new Employee() { Name = "Barry" });
foreach (var item in list) {
Console.WriteLine(item.Name);
}
}
}
public class Employee : IComparable<Employee> {
public string Name { get; set; }
public int Age { get; set; }
public Employee() {
}
public int CompareTo(Employee other) {
return string.Compare(Name, other.Name, true);
}
}
public class EmployeeAgeComparer : IComparer<Employee> {
public int Compare(Employee x, Employee y) {
return x.Age - y.Age;
}
}
public class SortedList<T> : IEnumerable<T> {
private List<T> _list;
public List<T> List {
get { return _list; }
set { _list = value; }
}
private EmployeeAgeComparer EmployeeComparer = new EmployeeAgeComparer();
public SortedList() {
_list = new List<T>();
}
public void Insert(T item) {
if (!_list.Contains(item)) {
_list.Add(item);
Sort(_list);
}
}
private void Sort(List<T> list) {
if (typeof(T) == typeof(Employee))
list.Sort((IComparer<T>)EmployeeComparer);
else
list.Sort();
}
public IEnumerator<T> GetEnumerator() {
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}