.Contains () कस्टम वर्ग की वस्तुओं की सूची पर


95

मैं .Contains()कस्टम ऑब्जेक्ट्स की सूची पर फ़ंक्शन का उपयोग करने का प्रयास कर रहा हूं

यह सूची है:

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

और 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;
    }
}

इसलिए मैं सूची के भीतर एक समान कार्ट्राप्ड खोजने की कोशिश करता हूं:

if (CartProducts.Contains(p))

लेकिन यह इसी तरह के कार्टप्रोडक्ट्स को नजरअंदाज करता है और मुझे यह पता नहीं लगता कि यह किस आईडी पर चेक करता है? या यह सब?

अग्रिम में धन्यवाद! :)

जवाबों:


119

आपको लागू करने IEquatableया ओवरराइड करने की आवश्यकता है Equals()औरGetHashCode()

उदाहरण के लिए:

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

4
लेकिन जहां है GetHashCode()?
जियोनी

1
आपको GetHashCode () लागू करने की आवश्यकता नहीं है। यह इसके बिना काम करता है।
user890332

141

यदि आप .NET 3.5 या नए का उपयोग कर रहे हैं, तो आप Anyएक्सटेंशन विधि के साथ "शामिल" चेक प्राप्त करने के लिए LINQ एक्सटेंशन विधियों का उपयोग कर सकते हैं :

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

यह उस उत्पाद के अस्तित्व की जांच करेगा CartProductsजिसके भीतर एक आईडी है जो आईडी से मेल खाता है p=>चेक पर प्रदर्शन करने के बाद आप किसी भी बूलियन अभिव्यक्ति को रख सकते हैं ।

यह LINQ-to-SQL प्रश्नों के साथ-साथ इन-मेमोरी क्वेरीज़ के लिए काम करने का लाभ भी है, जहाँ Containsनहीं है।


12

यह देखने के लिए जाँच करता है कि सूची में विशिष्ट वस्तु निहित है या नहीं।

आप सूची में खोज विधि का उपयोग कर बेहतर हो सकते हैं।

यहाँ एक उदाहरण है

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

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

उम्मीद है की वो मदद करदे

तुम भी LinQ पर देखना चाहिए - शायद इसके लिए overkill, लेकिन फिर भी एक उपयोगी उपकरण ...


1
कैसे Linq कभी overkill हो सकता है?
मेल गेरेट्स

@ एमईएल - क्यों एक क्वेरी में मिलाया जाता है और इस सरल के लिए कुछ निष्कर्ष टाइप करें? हालांकि उसने कहा, यह किसी और के लिए पठनीय हो सकता है, जो लामाओं से परिचित न हो ...
मार्टिन मिलन

+1 अच्छा स्पष्ट उदाहरण, वह विकल्प दिखाता है जो अन्यत्र परिवर्तनों से प्रभावित नहीं होगा (अर्थात यदि Equals()किसी कारण से विधि बदल गई है)
रॉलैंड शॉ

4

डिफ़ॉल्ट रूप से संदर्भ प्रकारों में संदर्भ समानता होती है (अर्थात दो उदाहरण केवल समान हैं यदि वे समान वस्तु हैं)।

आपको अपनी समानता को लागू करने के लिए ओवरराइड Object.Equals(और Object.GetHashCodeमैच करना) करना होगा। (और फिर एक समानता ==, ऑपरेटर को लागू करने के लिए यह अच्छा अभ्यास है ।)


1
ऑब्जेक्ट को क्यों ओवरराइड करें। ईक्ल्स, जिसके परिणाम कोड में कहीं और हो सकते हैं? मेरे लिए, इसके अनुसार खोज कोड में संशोधन करने के लिए और अधिक समझ में आता है, न कि वस्तु के अंतर्निहित वर्ग को खोजा जा रहा है ...
मार्टिन मिलन

क्या आप इसके कुछ उदाहरणों को सहेजते हैं। .Find () या ऑब्जेक्ट को ओवरराइड कर रहे हैं। Equals / GetHashCode?
जन जोहान्सन

यदि आप दो CartProductवस्तुओं की तुलना अलग-अलग जगहों पर अलग-अलग तरीके से करना चाहते हैं तो @ मॉर्टिन आईटी बहुत टूट जाएगा ।
रोलैंड शॉ

1
@ रॉलैंड - लेकिन मैं यह नहीं कह रहा हूं कि उन्हें यह देखना होगा कि तुलना कैसे काम करती है। यदि वह एक विशिष्ट वस्तु चाहता है, तो Contains () का उपयोग करें। यदि वह किसी निर्धारित मापदंड से मेल खाता कोई वस्तु चाहता है, तो एक उपयुक्त विधेय (लंबोदर अभिव्यक्ति) के साथ फाइंड () का उपयोग करें ... मैं वास्तव में तर्क दे रहा हूं कि आप तुलना कोड को सभी पर स्पर्श नहीं करते हैं - आप सिर्फ सही विधि पर कॉल करते हैं कार्य को पूरा करने के लिए प्रयास करें ...
मार्टिन मिलन

1
@ मर्टिन ने कहा कि मैंने आपकी टिप्पणी को "ओवरराइड Contains()" की तर्ज पर कुछ होने की गलत व्याख्या की । सहमत Find()हूं कि इस मुद्दे को हल कर सकता है, हालांकि मैं सुझाव दूंगा कि एक उपयुक्त समान विधि अन्य मामलों के भार में अधिक उपयोगी हो सकती है, क्योंकि ओपी ने यह नहीं बताया कि एक ही इकाई के दो उदाहरणों के संदर्भ अलग-अलग थे।
रोलैंड शॉ

1

आपको अपनी सूची से एक ऑब्जेक्ट बनाने की आवश्यकता है जैसे:

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

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

उस वस्तु को उनके गुणों द्वारा खोजे गए मूल्य का पता मिलता है: x.name

फिर आप सूची विधियों का उपयोग कर सकते हैं जैसे सम्‍मिलित या निकालें

if (lst.Contains(obj))
{
   lst.Remove(obj);
}

0

लागू करें override Equals()औरGetHashCode()

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

}

उपयोग किया गया:

if (CartProducts.Contains(p))

-1

यदि आप इस पर नियंत्रण रखना चाहते हैं तो आपको [IEquatable इंटरफ़ेस] लागू करने की आवश्यकता है [1]

[१]: http: // यह विधि डिफ़ॉल्ट समानता तुलनित्र का उपयोग करके समानता का निर्धारण करती है, जैसा कि टी के लिए IEquatable.Equals विधि के ऑब्जेक्ट के कार्यान्वयन द्वारा परिभाषित किया गया है (सूची में मूल्यों का प्रकार)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.