मैं सूची <T> में एक विशिष्ट तत्व कैसे पा सकता हूं?


114

मेरा आवेदन इस तरह एक सूची का उपयोग करता है:

List<MyClass> list = new List<MyClass>();

Addविधि का उपयोग करते हुए , सूची में एक और उदाहरण MyClassजोड़ा जाता है।

MyClass दूसरों के बीच, निम्नलिखित तरीके प्रदान करता है:

public void SetId(String Id);
public String GetId();

मैं विधि MyClassका उपयोग करने के माध्यम से एक विशिष्ट उदाहरण कैसे पा सकता हूं GetId? मुझे पता है कि Findविधि है, लेकिन मुझे नहीं पता कि क्या यह यहां काम करेगा ?!

जवाबों:


263

एक लंबोदर अभिव्यक्ति का उपयोग करें

MyClass result = list.Find(x => x.GetId() == "xy");

नोट: C # में गुणों के लिए एक अंतर्निहित सिंटैक्स है। लिखने वाले और सेटर के तरीकों को लिखने के बजाय (जैसा कि आप जावा से उपयोग किया जा सकता है), लिखें

private string _id;
public string Id
{
    get
    {
        return _id;
    }
    set
    {
        _id = value;
    }
}

valueएक प्रासंगिक कीवर्ड है जिसे केवल सेट एक्सेसर में जाना जाता है। यह संपत्ति को सौंपे गए मूल्य का प्रतिनिधित्व करता है।

चूंकि यह पैटर्न अक्सर उपयोग किया जाता है, इसलिए C # ऑटो-कार्यान्वित गुण प्रदान करता है । वे ऊपर दिए गए कोड का एक छोटा संस्करण हैं; हालाँकि, बैकिंग वैरिएबल छिपा हुआ है और पहुँच योग्य नहीं है (यह VB में कक्षा के भीतर से पहुँच योग्य है, हालाँकि)।

public string Id { get; set; }

आप बस गुणों का उपयोग कर सकते हैं जैसे कि आप किसी क्षेत्र में पहुँच रहे थे:

var obj = new MyClass();
obj.Id = "xy";       // Calls the setter with "xy" assigned to the value parameter.
string id = obj.Id;  // Calls the getter.

गुणों का उपयोग करते हुए, आप इस तरह सूची में मौजूद वस्तुओं की खोज करेंगे

MyClass result = list.Find(x => x.Id == "xy"); 

यदि आपको केवल-पढ़ने के लिए संपत्ति चाहिए, तो आप ऑटो-कार्यान्वित गुणों का भी उपयोग कर सकते हैं:

public string Id { get; private set; }

यह आपको Idकक्षा के भीतर सेट करने में सक्षम बनाता है लेकिन बाहर से नहीं। यदि आपको इसे व्युत्पन्न वर्गों में सेट करने की आवश्यकता है और साथ ही आप सेटर की सुरक्षा भी कर सकते हैं

public string Id { get; protected set; }

और अंत में, आप गुणों को घोषित कर सकते हैं virtualऔर उन्हें व्युत्पन्न वर्गों में ओवरराइड कर सकते हैं, जिससे आप गेटर्स और सेटर के लिए अलग-अलग कार्यान्वयन प्रदान कर सकते हैं; बस के रूप में साधारण आभासी तरीकों के लिए।


C # 6.0 (Visual Studio 2015, Roslyn) के बाद से आप इनलाइन इनिशलाइज़र के साथ गेटटर-ओनली ऑटो-प्रॉपर्टीज़ लिख सकते हैं

public string Id { get; } = "A07"; // Evaluated once when object is initialized.

आप इसके बजाय कंस्ट्रक्टर के भीतर गेटटर-केवल गुणों को इनिशियलाइज़ कर सकते हैं। गेटर-केवल ऑटो-गुण हैं सच केवल पढ़ने के लिए गुण, एक निजी सेटर के साथ स्वत: लागू किया गुण के विपरीत है।

यह ऑटो-गुण पढ़ने-लिखने के साथ भी काम करता है:

public string Id { get; set; } = "A07";

C # 6.0 के साथ शुरुआत करके आप अभिव्यक्ति-शारीरिक सदस्यों के रूप में भी गुण लिख सकते हैं

public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call.
// Instead of
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } }

देखें: .NET कंपाइलर प्लेटफ़ॉर्म ("रोज़लिन")
         C # 6 में नई भाषा सुविधाएँ

C # 7.0 के साथ शुरू , दोनों, गेटटर और सेटर, अभिव्यक्ति निकायों के साथ लिखा जा सकता है:

public string Name
{
    get => _name;                                // getter
    set => _name = value;                        // setter
}

ध्यान दें कि इस मामले में सेटर एक अभिव्यक्ति होना चाहिए। यह एक बयान नहीं हो सकता। उपरोक्त उदाहरण काम करता है, क्योंकि C # में असाइनमेंट का उपयोग एक्सप्रेशन के रूप में या स्टेटमेंट के रूप में किया जा सकता है। असाइनमेंट एक्सप्रेशन का मान असाइन किया गया मान है, जहाँ असाइनमेंट स्वयं एक साइड इफेक्ट है। यह आपको एक बार में एक से अधिक वेरिएबल के लिए मान निर्दिष्ट करने की अनुमति देता है: बयानों के x = y = z = 0समान है x = (y = (z = 0))और इसका प्रभाव भी है x = 0; y = 0; z = 0;

भाषा का अगला संस्करण, C # 9.0, शायद नवंबर 2020 में उपलब्ध है, केवल पढ़ने के लिए (या बेहतर इनिशियलाइज़-एक बार) गुण है कि आप एक वस्तु इनिशलाइज़र में इनिशियलाइज़ कर सकते हैं। गटर-केवल गुणों के साथ वर्तमान में यह संभव नहीं है।

public string Name { get; init; }

var c = new C { Name = "c-sharp" };

2
शानदार जवाब, धन्यवाद। डीबी ऑपरेशन के लिए यह कुछ इस तरह दिखेगा: IQueryable<T> result = db.Set<T>().Find(//just id here//).ToList();यह पहले से ही पता होगा कि आप प्राथमिक कुंजी की तलाश कर रहे हैं। सिर्फ जानकारी के लिए।
श्री ब्लोंड

मुझे पता है कि यह एक पुराना उत्तर है, लेकिन मैं गेट को अलग कर दूंगा और अलग-अलग तरीकों से सेट करूंगा, ताकि मूल्य गलती से तुलना के दौरान सेट न हो।
जोएल ट्रूगर

@JoelTrauger: एक तुलना संपत्ति को पढ़ती है और इसलिए केवल गेटर को बुलाता है।
ओलिवियर जैकोट-डेसकॉम्बस

यह सच है, लेकिन एक आकस्मिक असाइनमेंट सेटर को बुलाएगा और संपत्ति को संशोधित करेगा। देखें return object.property = valueबनामreturn object.property == value
जोएल ट्रैगर

एक अलग सेट विधि का आकस्मिक कॉल संपत्ति को भी संशोधित करेगा। मैं यह नहीं देखता कि अलग-अलग सेट किए गए तरीके सुरक्षा को कैसे बेहतर बना सकते हैं।
ओलिवियर जैकोट-डेसकोम्बर्स

19
var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );

या यदि केवल एक है और आप इसे लागू करना चाहते हैं तो ऐसा कुछ SingleOrDefaultहो सकता है जैसा आप चाहते हैं

var item = list.SingleOrDefault( x => x.GetId() == "TARGET" );

if ( item == null )
    throw new Exception();

यदि आप अपवाद को फेंकना चाहते हैं तो आप सिंगलऑर्फ़ॉल्ट का उपयोग क्यों करेंगे, सिंगल का उपयोग करें ()
कोड का नाम जैक


6

या यदि आप LINQ का उपयोग करना पसंद नहीं करते हैं तो आप इसे पुराने स्कूल में कर सकते हैं:

List<MyClass> list = new List<MyClass>();
foreach (MyClass element in list)
{
    if (element.GetId() == "heres_where_you_put_what_you_are_looking_for")
    {

        break; // If you only want to find the first instance a break here would be best for your application
    }
}

4

आप LINQ एक्सटेंशन का भी उपयोग कर सकते हैं :

string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();

4
या फ़र्स्ट का दूसरा ओवरलोड:MyClass result = list.First(m => m.GetId() == id);
मार्सेल गोसलिन

3

आप गुमनाम तरीके से सिंटैक्स का उपयोग करते हुए लिखे गए विधेय के साथ अपनी समस्या को सबसे अधिक संक्षेप में हल कर सकते हैं:

MyClass found = list.Find(item => item.GetID() == ID);

0
public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, यह समझाने के लिए बेहतर है कि समस्या को कैसे हल किया जाए और उदाहरण या संदर्भ के रूप में कोड प्रदान किया जाए। कोड-केवल उत्तर भ्रामक और संदर्भ की कमी हो सकते हैं।
रॉबर्ट कोलंबिया

0

आप अपने खोज मापदंड रखने के लिए एक खोज चर बना सकते हैं। यहाँ डेटाबेस का उपयोग करके एक उदाहरण दिया गया है।

 var query = from o in this.mJDBDataset.Products 
             where o.ProductStatus == textBox1.Text || o.Karrot == textBox1.Text 
             || o.ProductDetails == textBox1.Text || o.DepositDate == textBox1.Text 
             || o.SellDate == textBox1.Text
             select o;

 dataGridView1.DataSource = query.ToList();

 //Search and Calculate
 search = textBox1.Text;
 cnn.Open();
 string query1 = string.Format("select * from Products where ProductStatus='"
               + search +"'");
 SqlDataAdapter da = new SqlDataAdapter(query1, cnn);
 DataSet ds = new DataSet();
 da.Fill(ds, "Products");
 SqlDataReader reader;
 reader = new SqlCommand(query1, cnn).ExecuteReader();

 List<double> DuePayment = new List<double>();

 if (reader.HasRows)
 {

  while (reader.Read())
  {

   foreach (DataRow row in ds.Tables["Products"].Rows)
   {

     DuePaymentstring.Add(row["DuePayment"].ToString());
     DuePayment = DuePaymentstring.Select(x => double.Parse(x)).ToList();

   }
  }

  tdp = 0;
  tdp = DuePayment.Sum();                        
  DuePaymentstring.Remove(Convert.ToString(DuePaymentstring.Count));
  DuePayment.Clear();
 }
 cnn.Close();
 label3.Text = Convert.ToString(tdp + " Due Payment Count: " + 
 DuePayment.Count + " Due Payment string Count: " + DuePaymentstring.Count);
 tdp = 0;
 //DuePaymentstring.RemoveRange(0,DuePaymentstring.Count);
 //DuePayment.RemoveRange(0, DuePayment.Count);
 //Search and Calculate

यहां "चर क्वेरी" खोज चर के माध्यम से आपके द्वारा दिए जा रहे खोज मापदंड उत्पन्न कर रही है। फिर "ड्यूपायमेंटस्ट्रिंग.सेलेक्ट" आपके दिए गए मानदंडों से मेल खाते डेटा का चयन कर रहा है। यदि आपको समझने में समस्या हो तो बेझिझक पूछें।

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