. Berisi () di daftar objek kelas kustom

95

Saya mencoba menggunakan .Contains()fungsi tersebut pada daftar objek khusus

Ini daftarnya:

List<CartProduct> CartProducts = new List<CartProduct>();

Dan CartProduct:

public class CartProduct
{
    public Int32 ID;
    public String Name;
    public Int32 Number;
    public Decimal CurrentPrice;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="ID">The ID of the product</param>
    /// <param name="Name">The name of the product</param>
    /// <param name="Number">The total number of that product</param>
    /// <param name="CurrentPrice">The currentprice for the product (1 piece)</param>
    public CartProduct(Int32 ID, String Name, Int32 Number, Decimal CurrentPrice)
    {
        this.ID = ID;
        this.Name = Name;
        this.Number = Number;
        this.CurrentPrice = CurrentPrice;
    }
    public String ToString()
    {
        return Name;
    }
}

Jadi saya mencoba menemukan produk keranjang serupa di dalam daftar:

if (CartProducts.Contains(p))

Tapi itu mengabaikan cartproducts serupa dan saya sepertinya tidak tahu apa yang diperiksa - ID? atau semuanya?

Terima kasih sebelumnya! :)

Jan Johansen
sumber

Jawaban:

119

Anda perlu menerapkan IEquatableatau mengganti Equals()danGetHashCode()

Sebagai contoh:

public class CartProduct : IEquatable<CartProduct>
{
    public Int32 ID;
    public String Name;
    public Int32 Number;
    public Decimal CurrentPrice;

    public CartProduct(Int32 ID, String Name, Int32 Number, Decimal CurrentPrice)
    {
        this.ID = ID;
        this.Name = Name;
        this.Number = Number;
        this.CurrentPrice = CurrentPrice;
    }

    public String ToString()
    {
        return Name;
    }

    public bool Equals( CartProduct other )
    {
        // Would still want to check for null etc. first.
        return this.ID == other.ID && 
               this.Name == other.Name && 
               this.Number == other.Number && 
               this.CurrentPrice == other.CurrentPrice;
    }
}
Rowland Shaw
sumber
4
tapi dimana GetHashCode()?
zionpi
1
Anda tidak perlu mengimplementasikan GetHashCode (). Ia bekerja tanpa itu.
pengguna890332
141

Jika Anda menggunakan .NET 3.5 atau yang lebih baru, Anda dapat menggunakan metode ekstensi LINQ untuk mendapatkan pemeriksaan "berisi" dengan Anymetode ekstensi:

if(CartProducts.Any(prod => prod.ID == p.ID))

Ini akan memeriksa keberadaan produk yang di CartProductsdalamnya memiliki ID yang cocok dengan ID p. Anda dapat meletakkan ekspresi boolean apa pun setelah =>untuk melakukan pemeriksaan.

Ini juga memiliki keuntungan bekerja untuk kueri LINQ-to-SQL serta kueri dalam memori, di mana Containstidak.

Paul Turner
sumber
12

Ia memeriksa untuk melihat apakah objek tertentu terdapat dalam daftar.

Anda mungkin lebih baik menggunakan metode Temukan dalam daftar.

Berikut contohnya

List<CartProduct> lst = new List<CartProduct>();

CartProduct objBeer;
objBeer = lst.Find(x => (x.Name == "Beer"));

Semoga membantu

Anda juga harus melihat LinQ - mungkin berlebihan untuk ini, tetapi alat yang berguna tetap ...

Martin Milan
sumber
1
bagaimana Linq bisa berlebihan?
Mel Gerats
@MEL - Mengapa tercampur dalam kueri dan jenis inferensi untuk sesuatu yang sederhana ini? Meskipun demikian, ini mungkin lebih mudah dibaca oleh seseorang yang tidak terbiasa dengan lamda ...
Martin Milan
+1 Contoh jelas yang bagus, yang menunjukkan opsi yang tidak akan terpengaruh oleh perubahan di tempat lain (yaitu jika Equals()metode diubah karena alasan apa pun)
Rowland Shaw
4

Secara default jenis referensi memiliki persamaan referensi (yaitu dua contoh hanya sama jika mereka adalah objek yang sama).

Anda perlu mengganti Object.Equals(dan Object.GetHashCodemencocokkan) untuk menerapkan persamaan Anda sendiri. (Dan ini merupakan praktik yang baik untuk mengimplementasikan kesetaraan ==,, operator.)

Richard
sumber
1
Mengapa mengganti Object.Equals, yang dapat memiliki konsekuensi di tempat lain dalam kode? Bagi saya, lebih masuk akal untuk mengubah kode pencarian yang sesuai, dan bukan kelas objek yang dicari ...
Martin Milan
Apakah Anda memiliki beberapa contoh ini, .Find () atau menimpa Object.Equals / GetHashCode?
Jan Johansen
@Martin IT akan sangat rusak jika Anda ingin perbandingan dua CartProductobjek berperilaku berbeda di tempat yang berbeda.
Rowland Shaw
1
@Rowland - Tapi saya tidak mengatakan dia harus mengubah cara kerja perbandingan. Jika dia menginginkan objek tertentu, gunakan Contains (). Jika dia ingin objek apa pun yang cocok dengan kriteria tertentu, gunakan Find () dengan predikat yang sesuai (ekspresi lamda) ... Saya sebenarnya berpendapat bahwa Anda sama sekali tidak menyentuh kode perbandingan - Anda cukup memanggil metode yang benar di daftar untuk tugas yang Anda coba capai ...
Martin Milan
1
@Martin Muncul Saya salah menafsirkan komentar Anda menjadi sesuatu di sepanjang baris "menimpa Contains()". Setuju yang Find()dapat menyelesaikan masalah, meskipun saya akan menyarankan memiliki metode sama yang sesuai mungkin lebih berguna dalam banyak kasus lain, karena OP tidak melihat bahwa referensi untuk dua contoh dari entitas yang sama berbeda.
Rowland Shaw
1

Anda perlu membuat objek dari daftar Anda seperti:

List<CartProduct> lst = new List<CartProduct>();

CartProduct obj = lst.Find(x => (x.Name == "product name"));

Objek itu mendapatkan nilai yang terlihat dengan menelusuri propertinya: x.name

Kemudian Anda dapat menggunakan metode Daftar seperti Berisi atau Hapus

if (lst.Contains(obj))
{
   lst.Remove(obj);
}
José Chavez
sumber
0

Menerapkan override Equals()danGetHashCode()

public class CartProduct
{
    public Int32 ID;
    ...

    public CartProduct(Int32 ID, ...)
    {
        this.ID = ID;
        ...
    }

    public override int GetHashCode()
    {
        return ID;
    }

    public override bool Equals(Object obj)
        {
            if (obj == null || !(obj is CartProduct))
                return false;
            else
                return GetHashCode() == ((CartProduct)obj).GetHashCode();
        }

}

bekas:

if (CartProducts.Contains(p))
A. Morel
sumber
-1

Jika Anda ingin mengontrol hal ini, Anda perlu mengimplementasikan [antarmuka IEquatable] [1]

[1]: http: // Metode ini menentukan kesetaraan dengan menggunakan pembanding kesetaraan default, seperti yang didefinisikan oleh implementasi objek dari metode IEquatable.Equals untuk T (jenis nilai dalam daftar).

Gerrie Schenck
sumber