2010-07-19 10 views
10

में Nullable का उपयोग करते समय गॉटचास मैंने अभी एक घटक पर लिखना शुरू कर दिया है जहां मुझे लगता है कि यह कुछ मूल्यों को घोषित करने के लिए उपयोगी हो सकता है, बजाय उन्हें डिफ़ॉल्ट मानों का सहारा देने की बजाय। हालांकि, मुझे एहसास हुआ कि मैंने कभी भी non-nullable-type? सिंटैक्स या Nullable<T> प्रकार पहले इस्तेमाल नहीं किया है, इसलिए शायद कुछ गॉथैस हैं जो जल्द ही बाहर निकल जाएंगे और मुझे काट लेंगे। तो ... सी # 4

  • क्या जब Nullable<T> और आशुलिपि ? सिंटैक्स का उपयोग सबसे बड़ी gotchas कर रहे हैं?

  • मैं उनके आसपास कैसे काम करूं?

  • जब मैं उनका उपयोग करना शुरू करता हूं तो मेरे लिए उपलब्ध सबसे बड़े फायदे/नई संभावनाएं क्या हैं?

+9

का उपयोग कर अपने कोड लिखें द्वारा। जब यह उड़ाता है तो वापस आओ। यह रॉकेट विज्ञान नहीं है। –

+3

@ हंस, मैं असहमत हूं: समस्याओं की उम्मीद करने की कोशिश करने की कोई बुरा बात नहीं है ... मुझे यकीन है कि उत्तर कई लोगों के लिए उपयोगी होंगे –

+0

@ क्लोजर्स: मुझे एहसास है कि मुझे समुदाय में वापस आना होगा जब मेरे पास "असली" समस्या होती है, लेकिन चूंकि यह एक पूरी तरह से नई अवधारणा है, इसलिए मुझे नहीं लगता था कि यह मुझे इलाके को स्काउट करने में मदद करने के लिए चोट पहुंचाएगा। यदि यह अवधारणा बहुत कठिन नहीं है, तो हो सकता है कि मैं अधिक सतर्क रहूं - लेकिन यह उन क्षेत्रों में से एक हो सकता है जहां आप रूकी गलतियों को बांधने के लिए बाध्य हैं, और जहां उन्हें स्पॉट करना मुश्किल हो सकता है। मार्क बेयर्स का जवाब उन चीज़ों का एक उत्कृष्ट उदाहरण है जिन्हें मैं ढूंढ रहा था। –

उत्तर

18

एक आम गोचा एक सशर्त अभिव्यक्ति के साथ एक निरर्थक चर को असाइन करने का प्रयास कर रहा है इस प्रकार है:

bool useDefault = true; 
int defaultValue = 50; 
int? y = useDefault ? defaultValue : null; 

पहली नज़र में इस तरह से काम करना चाहिए लग सकता है, लेकिन वास्तव में यह एक संकलन त्रुटि देता है:

 
Type of conditional expression cannot be determined because there is no 
implicit conversion between 'int' and '<null>' 

समाधान: एक या संभावित परिणामों के दोनों के लिए एक वर्णक जोड़ने:

int? y = useDefault ? defaultValue : (int?)null; 

आम तौर पर कम देखी गई: आम तौर पर यह माना कि पूर्णांकों a <= 5 औरके लिए सुरक्षित हैसमकक्ष हैं। यह धारणा निरर्थक पूर्णांक के लिए सच नहीं है।

int? x = null; 
Console.WriteLine(x <= 5); 
Console.WriteLine(!(x > 5)); 

परिणाम:

 
False 
True 

समाधान: अशक्त मामले को अलग से संभाल।


यहाँ से ऊपर का एक और मामूली बदलाव है:

int? y = null; 
int? z = null; 
Console.WriteLine(y == z); 
Console.WriteLine(y <= z); 

आउटपुट:

 
True 
False 

तो yz को बराबर है, लेकिन यह कम से कम या बराबर करने के लिए z

समाधान: फिर, शून्य मामले को अलग से इलाज करना आश्चर्य से बच सकता है।

+0

एंटिटी फ्रेमवर्क ने मुझे बहुत ही उपयोगी तरीके से जानने के लिए बहुत उपयोगी बताया – msarchet

1

आप .HasValue कर सकते हैं की जाँच करने के लिए यदि चर रिक्त है

आप

myvar = nullablevar ?? defaultvalue; //will set defaultvalue if nullablevar is null 

और कुछ कर सकते हैं, यह ग # करने के लिए नया नहीं है 4

read this for more information

+0

वास्तव में "गॉचाचा" नहीं है, लेकिन –

0

मैं वर्तमान में 4.0 का उपयोग नहीं कर रहा हूं, लेकिन 2.0 में मुझे समस्या है, जैसे अधिकांश जेनरिक, int? आसानी से de-serialized नहीं किया जा सकता है। शायद 4.0 प्रतिबिंब के साथ बेहतर है, लेकिन डिफ़ॉल्ट एक्सएमएल सीरिएलाइज़र यूटिलिटीज इसे पढ़ नहीं सकता है इसका खुलासा किया गया है। यह काफी परेशान है।

+0

मुझे नहीं पता कि यह 2.0 में अलग है या नहीं, लेकिन 4.0 में जेनेरिक प्रकार जेनेरिक टाइपिंग में कोई समस्या नहीं है। .. एक 'Foo ' का क्रमशः एक्सएमएल –

+0

में '' तत्व में परिणाम 2.0 में, मुझे किसी भी सामान्य संपत्ति या फ़ील्ड का उपयोग करके XML deserializer (मैं केवल डिफ़ॉल्ट का उपयोग करता हूं) से प्रतिबिंब त्रुटि प्राप्त करता हूं। मुझे स्ट्रिंग [] या ArrayList करना है क्योंकि सूची क्रमबद्ध/deserialize नहीं होगा। यदि यह 4.0 में तय किया गया है, तो मेरा दिल खुशी से गाएगा। विरासत कोड पर काम बेकार है। –

0

निरर्थक का उपयोग करते समय अनजाने में डिफ़ॉल्ट मान सेट करें। मैंने इसे कुछ बार देखा है। उदाहरण के लिए। क्योंकि यह एक मूल्य के साथ प्रारंभ तो HasValue के लिए परीक्षण हमेशा सच है और _myMemberValue गलत तरीके से गलत मान के साथ सौंपा सकता है था

int? localVar = 0; 
// do something .. 
if (localVar.HasValue) 
    _myMemberValue = localVar.Value; 

localVar कभी नहीं रिक्त है।

- Editied, अधिक टिप्पणियां जोड़ने के लिए ----

उल्लेख करने के लिए भूल। मैंने देखा है कि एक बड़ा फायदा डेटाबेस में Nullable फ़ील्ड का प्रतिनिधित्व करने के लिए क्षेत्र का उपयोग करना है। यदि आप लिंक और ईएफ का उपयोग करते हैं तो यह स्वचालित रूप से जेनरेट भी होता है। लेकिन परंपरागत रूप से Nullable से पहले, यह मैन्युअल काम और त्रुटि क्षेत्र के अद्यतन को संभालने और इसे मूल्य या शून्य के साथ सेट करने का निर्णय लेने के लिए प्रवण है।

1

Nullable<T> एक विशेष मूल्य प्रकार है। यह मदद कर सकता है अगर आप समझते हैं कि यह वास्तव में कैसे काम करता है। इसके बारे में कुछ सूक्ष्म चीजें हैं जो तुरंत स्पष्ट नहीं हैं। मैंने लगभग here ब्लॉग किया।

वास्तविक गेटचास - बहुत से नहीं। बस सबसे बड़ा यह है कि स्पष्ट कलाकार InvalidOperationException (और NullReferenceException नहीं) फेंक सकता है। कंपाइलर आपको उत्पन्न होने वाली किसी भी समस्या के लिए मार्गदर्शन करना चाहिए।

1

Nullable<T> प्रकार थोड़ा असामान्य हैं; वे (कड़ाई से बोल रहे हैं) न तो मूल्य और न ही संदर्भ प्रकार, लेकिन बीच में अजीब कुछ। बॉक्सिंग/अनबॉक्सिंग और typeof विशेष रूप से विशेष नियम हैं इसलिए परिणाम कम अप्रत्याशित हैं।

विवरण के लिए, मैं जॉन स्कीट की पुस्तक C# in Depth की अनुशंसा करता हूं। यदि आपके पास पहले से ही इसका स्वामित्व नहीं है, तो आपको चाहिए। :)

10

कुछ लोग अक्सर आश्चर्यचकित होते हैं कि बॉक्स किए गए शून्य मूल्य प्रकार जैसी कोई चीज़ नहीं है। यदि आप कहते हैं:

int? x = 123; 
int? y = null; 
int z = 456; 
object xx = x; 
object yy = y; 
object zz = z; 

आप सोच सकते हैं कि ZZ एक बॉक्सिंग पूर्णांक, कि xx और yy नल ints बॉक्सिंग शामिल होता है के बाद से। वे नहीं करते। एक्सएक्स में एक बॉक्सिंग int है। yy शून्य पर सेट है।

1

सबसे अच्छे उपयोगों में से एक यह है कि यह डेटाबेस डेटाबेस के लिए काफी अच्छी तरह से मानचित्र करता है - इसे ध्यान में रखते हुए, आप इसका उपयोग करना चाहते हैं क्योंकि आप डेटाबेस में एक शून्य क्षेत्र करेंगे।

यह है कि, एक शून्य मान "अन्य" नहीं है - इसका अर्थ अज्ञात है, या इस समय अचूक है, या इस ऑब्जेक्ट/रिकॉर्ड में अन्य मान दिए गए हैं, यह किसी मान के लिए समझ में नहीं आता है ।

actualValue = userValue.HasValue ? userValue : defaultValue; 
: - उपयोगकर्ता वरीयताओं अशक्त हो सकता है, और वास्तविक मान

actualValue = userValue ?? defaultValue; 

?? हो जाएगा अशक्त सम्मिलित ऑपरेटर है - ऊपर निम्नलिखित के बराबर है अपनी स्थिति की तरह यह मान्य है लगता है

या

actualValue = (userValue != null) ? userValue : defaultValue; 

प्रलोभन मैं लोगों को सबसे अधिक बार त्रिकोणीय राज्य ध्वज के रूप में उपयोग कर रहा है bool? में देना देखें। यह समझ में नहीं आता है, क्योंकि सच/गलत/??? में कोई तीसरी संभावना नहीं है। आपके कोड को पढ़ने वाले अन्य लोगों को नीली पाठ, झूठा मतलब लाल पाठ, और शून्य का मतलब हरे रंग के पाठ का उपयोग करने के लिए सही है, यह जानने के लिए टिप्पणियों (सर्वोत्तम केस परिदृश्य) के माध्यम से खोदना होगा। इसके लिए enums का प्रयोग करें।

सबसे बड़ी जाल मैं लोगों में गिर जाते हैं देखते हैं कि - उसके अलावा, बस जाँच आदत हो अगर आपके nullables अशक्त कर रहे हैं - या तो तुलना शून्य पर के माध्यम से या .HasValue

+0

+1 'बूल' के बारे में नोट के लिए +1 त्रि-राज्य ध्वज =) –