डीटीओ के लिए अशक्त संदर्भ प्रकारों का उपयोग करने के लिए सर्वोत्तम अभ्यास


20

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

public class Item
{
    public string Id { get; set; } // PK so technically cannot be null
    public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
    public string Description { get; set; } // can be null
}

क्या इससे निपटने के लिए कोई सर्वोत्तम अभ्यास विकसित हो रहा है? मैं इसके बजाय एक गैर-पैरामीटर निर्माणकर्ता से बचना चाहूंगा, क्योंकि डायनमो एसडीके (साथ ही अन्य) में ओआरएम के साथ बुरी तरह से खेलता है।

यह लिखना मुझे अजीब लगता है public string Id { get; set; } = "";क्योंकि ऐसा कभी नहीं होगा क्योंकि Idपीके है और कभी भी अशक्त नहीं हो सकता। ""अगर यह किसी भी तरह से किया तो भी क्या फायदा होगा ?

तो इस पर कोई सबसे अच्छा अभ्यास?

  • क्या मुझे उन सभी को चिन्हित करना चाहिए, क्योंकि string?वे कभी-कभी अशक्त हो सकते हैं।
  • क्या मुझे इनिशियलाइज़ करना चाहिए Idऔर इसके Nameसाथ ही ""क्योंकि वे कभी भी अशक्त नहीं होना चाहिए और यह इरादे को दर्शाता है भले ही ""उसका कभी उपयोग नहीं किया जाएगा।
  • ऊपर का कुछ संयोजन

कृपया ध्यान दें: यह C # 8 अशक्त संदर्भ प्रकारों के बारे में है। यदि आप नहीं जानते कि वे क्या जवाब नहीं दे रहे हैं।


यह थोड़ा गंदा है, लेकिन आप बस #pragma warning disable CS8618फ़ाइल के शीर्ष पर थप्पड़ मार सकते हैं ।
20

7
इसके बजाय = "", आप = null!ऐसी संपत्ति को इनिशियलाइज़ करने के लिए उपयोग कर सकते हैं जिसे आप जानते हैं कि वह प्रभावी रूप से कभी नहीं होगी null(जब कंपाइलर के पास यह जानने का कोई तरीका नहीं है)। यदि Descriptionकानूनी रूप से हो सकता है null, तो इसे घोषित किया जाना चाहिए string?। वैकल्पिक रूप से, अगर डीटीओ के लिए अशक्तता जाँच मदद से अधिक उपद्रव है, तो आप केवल इस प्रकार के लिए NRTs को बंद करने के लिए टाइप इन #nullable disable/ रैप कर सकते हैं #nullable restore
जेरेन मोस्टर्ट

@JeroenMostert आपको इसे एक उत्तर के रूप में रखना चाहिए।
मैग्नस

3
@ मैग्नस: मैं "सर्वोत्तम प्रथाओं" के लिए पूछने वाले किसी भी प्रश्न का उत्तर देने में अनिच्छुक हूं; ऐसी बातें व्यापक और व्यक्तिपरक हैं। मुझे उम्मीद है कि ओपी अपनी टिप्पणी का उपयोग अपनी "सर्वश्रेष्ठ अभ्यास" विकसित करने के लिए कर सकता है।
जेरेन मोस्टर्ट

1
@ IvanGarcíaTopete: जबकि मैं मानता हूं कि प्राथमिक कुंजी के लिए एक स्ट्रिंग का उपयोग करना असामान्य है, और यहां तक ​​कि परिस्थितियों के आधार पर अनजाने में हो सकता है, ओपी का डेटा प्रकार की पसंद सवाल के लिए बहुत अप्रासंगिक है। यह आसानी से एक आवश्यक, गैर-अशक्त स्ट्रिंग संपत्ति पर लागू हो सकता है जो प्राथमिक कुंजी नहीं है, या यहां तक ​​कि एक स्ट्रिंग फ़ील्ड भी है जो समग्र प्राथमिक कुंजी का हिस्सा है, और सवाल अभी भी खड़ा होगा।
जेरेमी कैनी

जवाबों:


12

एक विकल्प के रूप में, आप के defaultसाथ संयोजन में शाब्दिक का उपयोग कर सकते हैंnull forgiving operator

public class Item
{
    public string Id { get; set; } = default!;
    public string Name { get; set; } = default!;
    public string Description { get; set; } = default!;
}

चूंकि आपका डीटीओ डायनेमोबीडी से आबाद है, आप MaybeNull/NotNull अशक्तता को नियंत्रित करने के लिए पोस्टकॉन्डिशन विशेषताओं का उपयोग कर सकते हैं

  • MaybeNull एक गैर-अशक्त वापसी मूल्य शून्य हो सकता है।
  • NotNull एक अशक्त वापसी मूल्य कभी भी अशक्त नहीं होगा।

लेकिन ये विशेषताएं केवल उन सदस्यों के कॉल करने के लिए अशक्त विश्लेषण को प्रभावित करती हैं जो उनके साथ एनोटेट हैं। आमतौर पर, आप इन विशेषताओं को रिटर्न, प्रॉपर्टीज़ और इंडेक्सर्स गेटर्स के तरीके पर लागू करते हैं।

तो, आप अपने सभी गुणों को गैर-अशक्त लोगों पर विचार कर सकते हैं और उन्हें MaybeNullविशेषता के साथ सजा सकते हैं , जिससे उन्हें संभावित nullमूल्य वापस मिल जाएगा

public class Item
{
    public string Id { get; set; } = "";
    [MaybeNull] public string Name { get; set; } = default!;
    [MaybeNull] public string Description { get; set; } = default!;
}

निम्न उदाहरण अद्यतन Itemवर्ग के उपयोग को दर्शाता है । जैसा कि आप देख सकते हैं, दूसरी पंक्ति चेतावनी नहीं दिखाती है, लेकिन तीसरा करती है

var item = new Item();
string id = item.Id;
string name = item.Name; //warning CS8600: Converting null literal or possible null value to non-nullable type.

या आप सभी गुणों को एक अशक्त बना सकते हैं और NoNullयह इंगित करने के लिए उपयोग कर सकते हैं कि रिटर्न वैल्यू null( Idउदाहरण के लिए) नहीं हो सकती है

public class Item
{
    [NotNull] public string? Id { get; set; }
    public string? Name { get; set; }
    public string? Description { get; set; }
}

चेतावनी पिछले उदाहरण के साथ ही होगी।

इसी तरह से काम करते हुए इनपुट पैरामीटर्स, प्रॉपर्टीज और इंडेक्स सेटरर्स के लिए AllowNull/DisallowNull प्रीकॉन्डिशन एट्रिब्यूट्स भी हैं ।

  • AllowNull एक गैर-अशक्त इनपुट तर्क शून्य हो सकता है।
  • DisallowNull एक अशक्त इनपुट तर्क कभी भी अशक्त नहीं होना चाहिए।

मुझे नहीं लगता कि यह आपकी मदद करेगा, क्योंकि आपकी कक्षा डेटाबेस से पॉपुलेटेड है, लेकिन आप उन्हें उपयोग करने के लिए गुण बसने वालों की अशक्तता को नियंत्रित कर सकते हैं, जैसे पहला विकल्प।

[MaybeNull, AllowNull] public string Description { get; set; }

और दूसरे के लिए

[NotNull, DisallowNull] public string? Id { get; set; }

इस देवभूमि लेख में पोस्ट / पूर्व शर्त के कुछ उपयोगी विवरण और उदाहरण पाए जा सकते हैं


6

इस परिदृश्य में पाठ्यपुस्तक का उत्तर string?आपकी Idसंपत्ति के लिए उपयोग करना है, लेकिन इसे भी[NotNull] विशेषता के साथ सजाने के लिए है:

public class Item
{
  [NotNull] public string? Id { get; set; }
  public string Name { get; set; }
  public string? Description { get; set; }
}

संदर्भ: प्रलेखन के अनुसार , [NotNull]विशेषता "निर्दिष्ट करती है कि एक आउटपुट शून्य नहीं है, भले ही संबंधित प्रकार इसे अनुमति देता है।"

तो, वास्तव में यहाँ क्या हो रहा है?

  1. सबसे पहले, string?रिटर्न प्रकार कंपाइलर को आपको चेतावनी देने से रोकता है कि संपत्ति निर्माण के दौरान असंगठित है और इस तरह से डिफ़ॉल्ट हो जाएगी null
  2. फिर, [NotNull]गुण एक चेतावनी को रोकता है जब संपत्ति को एक गैर-अशक्त चर को सौंपते हैं या इसे रोकने की कोशिश कर रहे हैं क्योंकि आप संकलक के स्थिर प्रवाह विश्लेषण को सूचित कर रहे हैं, व्यवहार में , यह संपत्ति कभी नहीं होगी null

चेतावनी: सभी मामलों के साथ C # की अशक्तता के संदर्भ में, तकनीकी रूप से कुछ भी नहीं है जो आपको अभी भी nullयहाँ एक मूल्य लौटा रहा है और इस प्रकार, संभवतः, कुछ डाउनस्ट्रीम अपवादों को पेश करता है; यानी, कोई आउट-ऑफ-द-बॉक्स रनटाइम सत्यापन नहीं है। सभी C # कभी भी एक संकलक चेतावनी है। जब आप परिचय [NotNull]देते हैं तो आप इसे प्रभावी रूप से अपने व्यवसाय तर्क के बारे में संकेत देकर उस चेतावनी से आगे निकल जाते हैं। जैसे, जब आप किसी प्रॉपर्टी के साथ एनोटेट करते हैं [NotNull], तो आप अपनी प्रतिबद्धता के लिए ज़िम्मेदारी ले रहे हैं कि " ऐसा कभी नहीं होगा क्योंकि Idपीके है और कभी भी अशक्त नहीं हो सकता है।"

उस प्रतिबद्धता को बनाए रखने में आपकी सहायता करने के लिए, आप अतिरिक्त रूप से गुण के साथ संपत्ति की व्याख्या करना चाह सकते हैं [DisallowNull]:

public class Item
{
  [NotNull, DisallowNull] public string? Id { get; set; }
  public string Name { get; set; }
  public string? Description { get; set; }
}

संदर्भ: प्रलेखन के अनुसार , [DisallowNull]विशेषता "निर्दिष्ट nullइनपुट के रूप में अस्वीकृत होने पर भी निर्दिष्ट प्रकार की अनुमति देती है।"

यह आपके मामले में प्रासंगिक नहीं हो सकता है क्योंकि डेटाबेस के माध्यम से मान असाइन किए जा रहे हैं, लेकिन [DisallowNull]विशेषता आपको एक चेतावनी देगी यदि आप कभी भी एक null(सक्षम) मान असाइन करने का प्रयास करते हैं Id, भले ही रिटर्न प्रकार अन्यथा इसके लिए अनुमति देता है अशक्त । कि संबंध में Idअभिनय करेंगे वास्तव में एक तरह string, जहाँ तक सी # के स्थिर प्रवाह विश्लेषण के रूप में संबंध है, जबकि यह भी अनुमति देता है मूल्य वस्तु के निर्माण और संपत्ति की आबादी के बीच अप्रारंभीकृत रहने के लिए।

नोट: जैसा कि दूसरों ने उल्लेख किया है, आप या Idतो डिफ़ॉल्ट मान निर्दिष्ट करके default!या समान रूप से समान परिणाम प्राप्त कर सकते हैं null!यह, वास्तव में, कुछ हद तक शैलीगत पसंद है। मैं अशक्त एनोटेशन का उपयोग करना पसंद करता हूं क्योंकि वे अधिक स्पष्ट हैं और दानेदार नियंत्रण प्रदान करते हैं, जबकि !कंपाइलर को बंद करने के तरीके के रूप में इसका दुरुपयोग करना आसान है । स्पष्ट रूप से एक संपत्ति को एक मूल्य के साथ आरंभ करना भी मुझ पर बुरा लगता है अगर मुझे पता है कि मैं उस मूल्य का उपयोग नहीं करने जा रहा हूं - भले ही वह डिफ़ॉल्ट हो।


-2

स्ट्रिंग एक संदर्भ प्रकार है और हमेशा अशक्त है, आपको कुछ विशेष करने की आवश्यकता नहीं है। आपको बाद में केवल समस्या हो सकती है यदि आप इस ऑब्जेक्ट प्रकार को दूसरे में मैप करना चाहते हैं, लेकिन आप बाद में इसे संभाल सकते हैं।


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