1

検索方法に問題があります。リスト内のすべての製品 (オブジェクト) を特定の名前で検索し、その後リストを価格で並べ替えることができる関数をコレクション クラス内に作成したいと考えています。

しかし、それは一般的であるため、リスト内のオブジェクトのフィールドに「到達」できません。誰か助けてくれませんか?

これが私が試したことです:

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..
    }
}

お時間をいただきありがとうございます。あなたが私の問題を理解し、私を助けてくれることを願っています。

4

4 に答える 4

0

あなたのクラスはジェネリックであり、ジェネリック パラメーターは制限されていないため、何でも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>カスタム クラスにa をキャストする方法はありません。コンストラクターを投稿していないので、新しいものを作成できることを確認できる唯一の方法ProductListは、アイテムを1つずつ追加することです。通常、コレクション型には、コレクション (通常は simple IEnumerable) を取り込んで初期化するコンストラクターがあります。

いずれにせよ、あなたのコレクション型は多くのことを行っているように見え、実装しようとしているメソッドはクラス メンバーとまったく対話しません。

于 2013-04-25T14:01:00.417 に答える
0

ProductListTをインターフェイス (または具体的な製品) に制限しないのはなぜですか?

public class ProductList : ICollection<IProduct>, IComparer<IProduct>
于 2013-04-25T14:01:30.880 に答える
0

さて、次の制約を追加できますT

interface IHasName
{
   string Name{get;}
}

したがって、コンパイラは T から名前を取得する方法を知っています。ただし、これはクラスに対してのみ行うことができます。あなたの管理下にないクラスについては、このインターフェースを実装するラッパーを書くことができます。

于 2013-04-25T14:01:59.150 に答える
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ソートしますが、新しいものを返し、それ自体は変更しませんListOutOrderByDescendingIOrderedEnumerable ListOut

ただし、もっと簡単なアプローチがあるかもしれないと思います:

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

これは、独自のコレクション クラスと を実装せずに使用できますIComparer<T>

于 2013-04-25T14:00:28.607 に答える