क्या मैं C # अशक्त संदर्भों को बता सकता हूं कि एक विधि एक क्षेत्र पर प्रभावी रूप से एक शून्य जांच है


14

निम्नलिखित कोड पर विचार करें:

#nullable enable
class Foo
{
    public string? Name { get; set; }
    public bool HasName => Name != null;
    public void NameToUpperCase()
    {
        if (HasName)
        {
            Name = Name.ToUpper();
        }
    }
}

Name = Name.ToUpper () पर मुझे एक चेतावनी मिलती है कि Name एक संभावित अशक्त संदर्भ है, जो स्पष्ट रूप से गलत है। मैं इस चेतावनी को HasName को टाल कर ठीक कर सकता हूं, इसलिए शर्त यह है कि (Name! = Null)।

क्या ऐसा कोई तरीका है जिससे मैं संकलक को निर्देश दे सकूँ कि हसननाम की एक सच्ची प्रतिक्रिया का नाम पर एक गैर-अशक्तता बाधा है?

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


1
IMO आपको HasValueएक अशक्त प्रकार पर उपयोग करना चाहिए , इसके खिलाफ जांच नहीं करनी चाहिए null। यह शायद आपकी समस्या को प्रभावित नहीं करता है।
फ़्रेड्रिक

मुझे लगता है कि आपके लिए मामला है, तो आप कोड को #nullable disableफिर #nullable enableया restoreउसके बाद ( docs.microsoft.com/en-us/dotnet/csharp/… ) के साथ लपेट सकते हैं ।
GaryNg

5
आप "डैमिट" !ऑपरेटर का उपयोग कर सकते हैं । if(HasName) { Name = Name!.ToUpper(); }
जन पाओलो गो

1
एक बहु-थ्रेड एप्लिकेशन के लिए, आप का नाम हसन नाम की जांच के बाद शून्य हो सकता है, संपत्ति पर वापस जाने के बजाय स्थानीय रूप से चर का उपयोग करना (जो जानता है कि संपत्ति अपने गॉटर में क्या कर सकती है) कुछ फंकी बग देने जा रही है (याद रखें एक इवेंट हैंडलर का उपयोग करना जहां यह हुआ है)
XIU

जवाबों:


3

मैंने चारों ओर से अलग-अलग विशेषताओं को देखा System.Diagnostics.CodeAnalysisऔर मुझे कुछ भी लागू नहीं मिला, जो बहुत निराशाजनक है। आप जो चाहते हैं, वह आपको प्राप्त हो सकता है:

public bool TryGetName([NotNullWhen(true)] out string? name)
{
    name = Name;
    return name != null;
}

public void NameToUpperCase()
{
    if (TryGetName(out var name))
    {
        Name = name.ToUpper();
    }
}

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


2
ऐसा लगता है कि हमें और अधिक विशेषताओं की आवश्यकता है या टाइपस्क्रिप्ट के दावे की तरह कुछ है
Stilgar

मैं इसे उत्तर के रूप में चुनता हूँ, क्योंकि यह प्रतीत होता है कि असली उत्तर, जैसा कि मुझे डर था, "नहीं, सी # अभी तक ऐसा नहीं करता है।"
जॉन मेलविले

@JohnMelville मैं या तो इस तरह की सुविधा के लिए प्रस्ताव नहीं पा रहा था, इसलिए मुझे नहीं लगता कि हम जल्द ही इस बदलाव की उम्मीद कर सकते हैं।
V0ldek

2
@XIU इस पहलू में संकलक पहले से ही ढीला है। यदि आप करते हैं if(Name != null) return Null.ToUpper(), तो तकनीकी रूप से यह एक TOCTOU जाति की स्थिति होने पर भी, एक अशांति के लिए कोई चेतावनी नहीं होगी। मुझे याद है कि मैड्स टॉर्गेर्सन बोल रहे थे कि वे ऐसा कैसे मानते थे, लेकिन यह इतने सारे झूठे सकारात्मक उत्पन्न करता है कि पूरी तरह से अशक्त संदर्भ प्रकार की सुविधा प्रभावी रूप से बेकार हो जाएगी - 99% समय जब आपके गुणों को किसी अन्य धागे द्वारा नहीं बदला जाएगा। तो आपको बस इतना करना होगा कि एक विशेषता है जो इस संपत्ति पर चेक को दूसरी संपत्ति पर शून्य के लिए चेक के रूप में माना जाएगा।
V0ldek

2
मैंने तय किया "समस्या के लिए एक प्रस्ताव नहीं मिल सकता है"। ( github.com/dotnet/csharplang/issues/2997 ) मुझे शुभकामनाएं।
जॉन मेलविले

-10

स्ट्रिंग एक संदर्भ प्रकार है, और अशक्त (जैसे int?) अशक्त मान प्रकार है। तो आप वास्तव में ऐसा नहीं कर सकते हैं string? myString; आपको इसकी क्या आवश्यकता है:

class Foo
{
    public string Name { get; set; }
    public bool HasName => !String.IsNullOrEmpty(Name);  ////assume you want empty to be treated same way as null
    public void NameToUpperCase()
    {
        if (HasName)
        {
            Name = Name.ToUpper();
        }
    }
}

आप पुराने हो चुके हैं docs.microsoft.com/en-us/dotnet/csharp/language-reference/...
Aluan हद्दाद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.