如何使用集合类中的方法对列表排序

本文关键字:列表 排序 方法 何使用 集合类 | 更新日期: 2023-09-27 18:11:03

我有一个搜索方法的一些问题。我想在我的集合类中创建一个函数,它可以在我的列表中找到具有特定名称的所有产品(对象),然后按价格对列表进行排序。

但是因为它是通用的,所以我不能"到达"列表中对象中的字段。有人能帮帮我吗?

这是我尝试过的:

public class ProductList<T> : ICollection<T>, IComparer<T>
{
    public List<T> _productList = new List<T>();
    // Some other methods

    // 1. try:
    public void FuncSearch_Name(string search_name, ProductList<Product> ListIn, out ProductList<Product> ListOut)
    {
        ListOut = ListIn.Where(x => x.Name.Equals(search_name)).ToList(); // Here it is complaining about that it cant not implicity convert a generic list to productlist (I dont really understand that)
    }

    // I have also tried like this:
    public void FuncSearch_name(string search_name, ref List<T> ListIn, out List<T> ListOut)
    {
        ListOut = ListIn.Where(x => x.Name.Equals(search_name)).ToList();
        ListOut.OrderByDescending(o => o.Price).ToList(); // Here it can't find Name and Price because "T" not contains them..
    }
}

谢谢你的时间。我希望你能理解我的问题,并能帮助我。

如何使用集合类中的方法对列表排序

为什么不让ProductList限制T到一个接口(或具体的产品)?

public class ProductList : ICollection<IProduct>, IComparer<IProduct>

那么,您可以为T添加额外的约束:

interface IHasName
{
   string Name{get;}
}
因此,编译器将知道如何从t中获取名称。然而,您只能对您的类执行此操作。对于不受您控制的类,您可以编写一个包装器来实现这个接口。

由于您的类是泛型的,并且泛型参数不受限制,因此T可以是任何,因此编译器无法知道您的对象具有Name属性。

看起来你的声明应该是:

public class ProductList<T> : ICollection<T>, IComparer<T> where T: Product
{
    public List<T> _productList = new List<T>();

如果Product有子类,或者只是

public class ProductList : ICollection<Product>, IComparer<Product> 
{
    public List<Product> _productList = new List<Product>();

也是不寻常的一个类型的集合实现IComparer。这通常是在一个单独的类中完成的。

仔细看看你的问题,ToList<Product>返回一个List<Product>。没有办法将List<Product>强制转换为您的自定义类。由于您没有发布构造函数,因此我可以看到您可以创建新ProductList的唯一方法是逐个添加项。通常,集合类型有一个构造函数,该构造函数接受一个集合(通常是一个简单的IEnumerable)来初始化它。

无论哪种方式,您的集合类型似乎做得太多,并且您试图实现的方法根本不与类成员交互。

嗯,实际上你正在实现IComparer<T>。这是你用来排序T对象的比较器吗?如果是,您可以将它用于List.Sort,它是就地,不像OrderByDescending:

public void FuncSearch_name(string search_name, ref List<T> ListIn, out List<T> ListOut)
{
    ListOut = ListIn.Where(x => x.Name.Equals(search_name)).ToList();
    ListOut.Sort(this);
}

这个Sort直接排序ListOut,而OrderByDescending返回一个新的IOrderedEnumerable,并且不改变 ListOut本身。

然而,我认为可能有一个更简单的方法:

public IEnumerable<Product> FindByName(string name)
{
    myProducts.Where(p => p.Name == name).OrderByDescending(p => p.Price);
}

您可以使用它,而不需要实现您自己的集合类和IComparer<T>