2014-04-10 9 views
5

मैं इस समाधान का उपयोग कर रहा मेरे कोड में एक श्रृंखलित अशक्त जांच करने के लिएसुरुचिपूर्ण रास्ता चेक

Cleaner way to do a null check in C#?

मैं बस नहीं कर सकते हम इसे इस तरह कर सोच रहा था।

bool returnValue = Helper.IsNull(nullPerson.contact.address.city); 

क्या यह और भी क्लीनर नहीं होगा?

मैं इस तरह के एक सामान्य समारोह

public static bool IsNull<T>(this T rootObj) 
{ 
    var visitor = new IsNullExpressionVisitor(); 
    //... 
    //... 
} 

लेखन की कोशिश की लेकिन फिर मैं कैसे इस rootObject से बाहर अभिव्यक्ति बनाने के लिए पर अटक गई।

+2

मुझे नहीं लगता कि उस हस्ताक्षर के साथ ऐसा करने का कोई तरीका है। लेकिन आप एक लैम्ब्डा में गुजरने के लिए बेहतर भाग्य हो सकता है। इस तरह: IsNull (() => nullPerson.contact.address.city)। –

+0

आप जिस डॉटनेट संस्करण का उपयोग कर रहे हैं उसके आधार पर, आप स्थैतिक वर्ग अनुबंध http://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.contract.aspx – JCorriveau

+0

का उपयोग कर सकते हैं आप वापसी मूल्य के रूप में क्या अपेक्षा करेंगे श्रृंखला में 'nullPerson.contact.address.city' अगर शून्य मूल्य है? – samy

उत्तर

4

इस तक पहुंचने का एक तरीका (हालांकि अभी भी कुछ हद तक गुंजाइश) a construct that's sometimes called a "Maybe" monad का उपयोग करना है।

कि का उपयोग करना, कोड कुछ इस तरह बन जाएगा (जो आप या पसंद करते हैं नहीं हो सकता है!):

string city = nullPerson.With(x => x.address) 
         .With(x => x.city); 

हालांकि, आनन्द क्योंकि C# is getting the "Safe Navigation" operator (?.) in the next version*.

इस नए ?. ऑपरेटर के साथ

, कोड होगा इस तरह दिखेगा:

city = nullPerson?.address?.city; 

(* कथित तौर पर ...)

+0

सुरक्षित नेविगेशन ऑपरेटर के लिए +1 :) – samy

+0

हां, मुझे विश्वास नहीं है कि सुविधा वास्तव में इसे सी # 6 में बना देगी ... शायद सी # 7? –

+0

क्या कोई यूज़र्वॉइस कहीं नहीं है जहां हम ऑपरेटर के लिए दबाव डाल सकते हैं? – samy

1

manyquestions एक ही समस्या का समाधान करने की कोशिश कर पढ़ने के बाद, मैं एक अंग पर बाहर जाना और कहते है कि वहाँ वर्तमान में वास्तव में सुरुचिपूर्ण श्रृंखलित अशक्त जांच, जहां सुरुचिपूर्ण के प्रत्येक घटक के लिए अविवेक नहीं जोड़ने का मतलब होगा बनाने के लिए कोई रास्ता नहीं होगा जंजीर।

एक लैम्ब्डा मूल्यांकन में श्रृंखला रैपिंग शायद समय में यह करने के लिए कम से कम भयानक तरीका है, और यह केवल में काम करेगा:

CheckNull<string>(() => nullPerson.contact.address.city); 

T CheckNull<T>(Func<T> f) { try { return f(); } catch { return default(T); } } 

मैं नहीं बल्कि कोशिश करने के लिए प्रोत्साहित करता हूँ और Law of Demeter का पालन करें जो कहता है कि आपकी वस्तु को उन वस्तुओं के आंतरिक कार्यों के बारे में नहीं पता होना चाहिए जिनके साथ काम कर रहा है और उन्हें वर्ग के पेड़ को छोड़ने के बजाय मूल्य को वापस करने के लिए कहें।

+0

खोदता है यह वास्तव में खराब प्रक्रिया का उपयोग करने के लिए पकड़ का उपयोग करने के लिए खराब अभ्यास है =) लेकिन आपकी विधि मेरे समाधान के बहुत करीब है: http://stackoverflow.com/a/34086283/4711853 –

0

कोई नहीं है। मैंने देखा है कि सभी मौजूदा समाधान समस्या से कहीं ज्यादा भयानक हैं। बहुत सारे चालाक समाधान सिर्फ अन्य लोगों के लिए यह समझना मुश्किल बनाते हैं कि कोड क्या कर रहा है।

city = selectedPerson.Contact.Address.City; 

आप क्या कर सकते एक संपत्ति में चेक संपुटित

City SelectedCity 
{ 
    get 
    { 
     if (selectedPerson == null || selectedPerson.Contact == null || selectedPerson.Contact.Address == null) 
      return null; 
     return selectedPerson.Contact.Address.City; 
    } 
} 

के बाद सभी चाहने के स्वभाव से है:

स्थिति है कि आप इस तरह से कुछ करना चाहता हूँ है गुणों की इस लंबी श्रृंखला तक पहुंचने के लिए आपके पास एक चयनित शहर की अवधारणा है। कोड सुरुचिपूर्ण नहीं है लेकिन कम से कम यह एक स्थान पर छिपा हुआ है और इसे पढ़ने वाला कोई भी व्यक्ति तुरंत "चयनितसिटी" क्या समझ सकता है।

0

मेरा उत्तर यहाँ देखें

https://stackoverflow.com/a/34086283/4711853

आप बस छोटा सा विस्तार विधि है, जो आपको इस तरह श्रृंखलित लैम्ब्डा लिखने के लिए खर्च कर लिख सकते हैं:

वर वैल = instance.DefaultOrValue (x => x .SecondInstance) .efaultOrValue (x => x.ThirdInstance) .efaultOrValue (x => x.Value);

आप इस विधि को कम कर सकते हैं

संबंधित मुद्दे