我在使用搜索方法时遇到了一些问题。 我想在我的集合类中创建一个函数,它可以在列表中找到具有特定名称的所有产品(对象),然后按价格对列表进行排序。
但是因为它是通用的,我无法“到达”列表中对象中的字段。 有人能帮帮我吗?
以下是我的尝试:
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..
}
}
感谢您的时间。我希望你能理解我的问题,并能帮助我。
答案 0 :(得分:0)
嗯,实际上你正在实施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
本身。< / p>
但是,我认为可能有一个更简单的方法:
public IEnumerable<Product> FindByName(string name)
{
myProducts.Where(p => p.Name == name).OrderByDescending(p => p.Price);
}
您可以在不实现自己的集合类和IComparer<T>
的情况下使用它。
答案 1 :(得分:0)
由于您的类是通用的,并且通用参数不受限制,T
可能任何,因此编译器无法知道您的对象具有{{1属性。
看起来您的声明应该是:
Name
如果Product有子类,或只是
public class ProductList<T> : ICollection<T>, IComparer<T> where T: Product
{
public List<T> _productList = new List<T>();
对于要实现public class ProductList : ICollection<Product>, IComparer<Product>
{
public List<Product> _productList = new List<Product>();
的类型集合,异常也是如此。通常情况下,这是在一个单独的类中完成的。
仔细观察您的问题,IComparer
会返回ToList<Product>
。无法将List<Product>
转换为自定义类。由于您没有发布构造函数,我可以看到您可以创建新List<Product>
的唯一方法是逐个添加项目。通常,colelction类型有一个构造函数,它接受一个集合(通常是一个简单的ProductList
)来初始化它。
无论哪种方式,您的集合类型似乎都做得很多,而您尝试实现的方法并没有;根本不与类成员交互。
答案 2 :(得分:0)
为什么不将ProductList限制为T
到接口(或具体产品)?
public class ProductList : ICollection<IProduct>, IComparer<IProduct>
答案 3 :(得分:0)
好吧,你可以为T
添加额外的约束:
interface IHasName
{
string Name{get;}
}
因此,编译器会知道如何从T获取名称。但是,您只能为您的类执行此操作。对于不受您控制的类,您只需编写一个实现此接口的包装器。