मैं यह कैसे सुनिश्चित कर सकता हूं कि FirstOrDefault <KeyValuePair> ने मान लौटा दिया है


91

यहाँ एक सरल संस्करण है जो मैं करने की कोशिश कर रहा हूँ:

var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");

var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

चूंकि 'xyz' शब्दकोष में मौजूद नहीं है, इसलिए FirstOrDefault विधि मान्य मान नहीं लौटाएगी। मैं इस स्थिति के लिए जाँच करने में सक्षम होना चाहता हूँ, लेकिन मुझे एहसास है कि मैं "null" परिणाम की तुलना नहीं कर सकता क्योंकि KeyValuePair एक स्पष्ट है। निम्नलिखित कोड अमान्य है:

if (day == null) {
    System.Diagnotics.Debug.Write("Couldn't find day of week");
}

हम आपको कोड संकलित करने का प्रयास करते हैं, विजुअल स्टूडियो निम्नलिखित त्रुटि फेंकता है:

Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>'

मैं कैसे जाँच सकता हूँ कि FirstOrDefault ने एक वैध मान लौटाया है?


1
आपके पास एक बग है, लेकिन मुझे लगता है कि यह एक कॉपी-पेस्ट चीज़ है: दिन एक सूची नहीं है, और आप KeyValpPair पर ऐड का उपयोग नहीं कर सकते।
कोबी

ओह ... आप सही हैं मैं स्मृति से टाइप कर रहा था और मैंने स्पष्ट रूप से गलती की थी। इस पर ध्यान दिलाने के लिए धन्यवाद।
desautelsj

1
यह शायद था: var days = new Dictionary <int, string> ();
यहां तक ​​कि Mien

जवाबों:


155

FirstOrDefaultयह वापस नहीं आता है, यह वापस लौटता है default(T)
आपको इसकी जांच करनी चाहिए:

var defaultDay = default(KeyValuePair<int, string>);
bool b = day.Equals(defaultDay);

से MSDN -Enumerable.FirstOrDefault<TSource> :

डिफ़ॉल्ट ( TSource ) यदि स्रोत खाली है; अन्यथा, स्रोत में पहला तत्व ।

टिप्पणियाँ:


16
+1, KeyValuePair एक मान प्रकार (संरचना) है, न कि एक संदर्भ प्रकार (वर्ग) या एक अशक्त मान प्रकार, इसलिए यह शून्य नहीं हो सकता है।
लुकास

6
@ paper1337 - धन्यवाद, लेकिन मैं कहां गायब हूं typeof? यह कोड संकलित करता है और काम करता है।
कोबी

3
मैं यहां आया क्योंकि यह मेरे लिए स्पष्ट नहीं था, क्या default(KeyValuePair<T1, T2>)परिणाम होगा। ठीक है, यह काफी स्पष्ट होना चाहिए था, कि यह एक खाली पीपीपी में परिणाम होगा। लेकिन जैसा कि "स्पष्ट होना" उचित अनुप्रयोगों को लिखने के लिए एक अच्छा तरीका नहीं है (और मेरा वर्तमान कार्यान्वयन बहुत स्पष्ट रूप से / इस मामले को स्पष्ट रूप से भड़काने के लिए जटिल है), मैंने इसे एक नई परियोजना के साथ आज़माया और - वास्तव में - यह KeyValuePairगुणों के साथ लौटा Keyऔर Valueजा रहा है दोनों NULL.... बस कुछ अन्य लोगों को इन 5 मिनट की मूर्खता को सुरक्षित करने के लिए ;-)
निकोलस

@ निकोलस - यहाँ कोई मूर्खता नहीं है। अपने लिए जांचना और अपने कोड को समझना सुनिश्चित करना हमेशा एक अच्छा विचार है। मैंने defaultकीवर्ड के लिए एक लिंक जोड़ा है , यह स्पष्ट रूप से यहां गायब है। धन्यवाद!
कोबी

1
@JeffBridgman - यह वास्तव में एक अच्छी बात है! विशेष रूप से यहां यह संभव नहीं है, क्योंकि हम साथ काम कर रहे हैं KeyValuePair। यदि आपके पास जेनेरिक कोड होता है, day.Equalsतो यह शून्य-सुरक्षित भी नहीं है, और मैंने इस्तेमाल किया होगाEqualityComparer<T>.Default.Equals(day, defaultDay)
कोबी

53

यह मेरी राय में सबसे स्पष्ट और संक्षिप्त तरीका है:

var matchedDays = days.Where(x => sampleText.Contains(x.Value));
if (!matchedDays.Any())
{
    // Nothing matched
}
else
{
    // Get the first match
    var day = matchedDays.First();
}

यह पूरी तरह से संरचनाओं के लिए अजीब डिफ़ॉल्ट मूल्य सामान का उपयोग करने के आसपास हो जाता है।


13
इसके साथ समस्या यह है कि संभावित (कार्यान्वयन के आधार पर) है कि आने वाले दिनों में दो बार गणना की जाएगी, या इससे भी बदतर, किसी भी () और पहले () कॉल के बीच के विभिन्न मान
लौटाएंगे

@RayBooysen ToArray या ToList की एक कॉल समस्या को हल करती है और आप Count / लंबाई और एक अनुक्रमणिका का उपयोग कर सकते हैं।
कंसोल

1
ध्यान दें कि @ रे का उत्तर यहां लागू नहीं होता है, क्योंकि daysDictionary<int,string>। इसलिए यह एक के रूप में विचार किया जाएगा IEnumerable<KeyValuePair<int,string>>, तो व्यवहार कर के रूप में जब की उम्मीद Any()है और First()कहा जाता है। मुझे लगता है कि अन्य कार्यान्वयन भी हैं जो अलग तरह से व्यवहार कर सकते हैं IEnumerable<>। मुझे नहीं पता कि मुझे कुछ याद आ रहा है या नहीं।
इमानुएल बेलिनी

0

आप इसके बजाय यह कर सकते हैं:

var days = new Dictionary<int?, string>();   // replace int by int?
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");

var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

और फिर :

if (day.Key == null) {
    System.Diagnotics.Debug.Write("Couldn't find day of week");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.