C# IComparer<;T>;列表排序的实现问题<;T>;

C# IComparer<;T>;列表排序的实现问题<;T>;,c#,C#,我在创建自己的列表结构时遇到了一些问题。我正在尝试创建一个名为SortedList的列表结构。其目标是在添加新项目后立即对其项目进行排序。这个列表在我使用它的项目中不会太大(最多50-100个项目)。然而,我通过添加一个简单的类Employee项进行测试,该类具有Name属性。我想让这个分类列表按员工的名字分类 这是我的尝试 雇员阶级 public class Employee : IComparer<Employee> { public string Name { get;

我在创建自己的列表结构时遇到了一些问题。我正在尝试创建一个名为SortedList的列表结构。其目标是在添加新项目后立即对其项目进行排序。这个列表在我使用它的项目中不会太大(最多50-100个项目)。然而,我通过添加一个简单的类Employee项进行测试,该类具有Name属性。我想让这个分类列表按员工的名字分类

这是我的尝试

雇员阶级

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
是否有type
int
,但在编译时它仍然有type
object
,这意味着它不能用作返回值。你需要一个演员来让它发挥作用:

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();
    }
}