NullReferenceException क्या है, और मैं इसे कैसे ठीक करूँ?


1875

मेरे पास कुछ कोड हैं और जब यह निष्पादित होता है, तो यह ए NullReferenceException, फेंकता है :

वस्तु का संदर्भ वस्तु की आवृत्ति अनुसार सेट नहीं। है।

इसका क्या मतलब है, और मैं इस त्रुटि को ठीक करने के लिए क्या कर सकता हूं?


VS अपवाद 2017 में अपवाद सहायक इस अपवाद के कारण का निदान करने में अधिक सहायक होगा - blogs.msdn.microsoft.com/visualstudio/2016/11/28/… न्यू एक्सेप्शन हेल्पर के तहत ।
ज़ेव स्पिट्ज़

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

@will ANE केवल तभी होना चाहिए जब एक अशक्त पैरामीटर के रूप में पारित हो। क्या आप एक उदाहरण दे सकते हैं कि क्या कोई ANE प्रश्न इस के डुप्लिकेट के रूप में बंद हुआ है?
जॉन सॉन्डर्स

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

जवाबों:


2415

कारण क्या है?

जमीनी स्तर

आप कुछ ऐसा उपयोग करने का प्रयास कर रहे हैं जो null(या NothingVB.NET में है)। इसका मतलब है कि आप इसे करने के लिए तैयार हैंnull , या आप इसे कभी भी किसी भी चीज़ के लिए सेट नहीं करते हैं।

और कुछ की तरह, nullचारों ओर से गुजर जाता है। अगर ऐसा है null में विधि 'ए', यह हो सकता है कि विधि "बी" एक पारित कर दिया null करने के लिए विधि 'ए'।

null अलग-अलग अर्थ हो सकते हैं:

    1. ऑब्जेक्ट वैरिएबल जो अनइंस्टाल्यूट होते हैं और इसलिए कुछ भी नहीं होने का संकेत देते हैं। इस मामले में, यदि आप ऐसी वस्तुओं के गुणों या विधियों का उपयोग करते हैं, तो यह एक कारण बनता है NullReferenceException
    1. डेवलपर यह इंगित करने के लिए जानबूझकर उपयोग nullकर रहा है कि कोई सार्थक मूल्य उपलब्ध नहीं है। ध्यान दें कि C # में चर के लिए अशक्त डेटाैटिप्स की अवधारणा है (जैसे डेटाबेस तालिकाओं में अशक्त क्षेत्र हो सकते हैं) - आप nullउन्हें यह इंगित करने के लिए असाइन कर सकते हैं कि इसमें कोई मान संग्रहीत नहीं है, उदाहरण के लिए int? a = null;जहां प्रश्न चिह्न इंगित करता है कि इसे शून्य में संग्रहीत करने की अनुमति है। परिवर्तनशील a। आप या तो के साथ if (a.HasValue) {...}या जाँच कर सकते हैं if (a==null) {...}। अशक्त चर, aइस उदाहरण की तरह , मूल्य को a.Valueस्पष्ट रूप से या सामान्य तरीके से उपयोग करने की अनुमति देते हैं a
      ध्यान दें कि इसे a.Valueएक के InvalidOperationExceptionबजाय फेंकता हैNullReferenceException अगर aहैnull- आपको पहले ही चेक कर लेना चाहिए, यानी अगर आपके पास एक और ऑन-न्यूलेबल वैरिएबल है int b;तो आपको असाइनमेंट करना चाहिए जैसे if (a.HasValue) { b = a.Value; }कम या कम if (a != null) { b = a; }

इस लेख के बाकी हिस्सों को और अधिक विस्तार से जाना जाता है और गलतियों को दिखाता है जो कई प्रोग्रामर अक्सर बनाते हैं जो कि नेतृत्व कर सकते हैं NullReferenceException

अधिक विशेष रूप से

runtimeफेंक एक NullReferenceException हमेशा एक ही बात मतलब है: आप एक संदर्भ का उपयोग करने की कोशिश कर रहे हैं, और संदर्भ आरंभ नहीं किया है (या यह था एक बार , प्रारंभ लेकिन है नहीं रह गया है प्रारंभ)।

इसका मतलब यह है कि संदर्भ है null, और आप एक nullसंदर्भ के माध्यम से सदस्यों (जैसे तरीकों) का उपयोग नहीं कर सकते । सबसे सरल मामला:

string foo = null;
foo.ToUpper();

यह NullReferenceExceptionदूसरी पंक्ति में फेंकेगा क्योंकि आप इंस्टेंस विधि ToUpper()को stringइंगित करने वाले संदर्भ पर कॉल नहीं कर सकतेnull

डिबगिंग

आप एक के स्रोत को कैसे पाते हैं NullReferenceException? अपवाद को देखने के अलावा, जो वास्तव में उस स्थान पर फेंक दिया जाएगा जहां यह होता है, विजुअल स्टूडियो में डीबगिंग के सामान्य नियम लागू होते हैं: रणनीतिक ब्रेकपॉइंट लगाएं और अपने चर का निरीक्षण करें , या तो उनके नामों पर माउस को मँडरा कर, एक को खोलकर ( क्विक) विंडो देखें या लोकल और ऑटो जैसे विभिन्न डिबगिंग पैनल का उपयोग करें।

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

प्रोग्राम को इस तरह से फॉलो करके, आप उस स्थान का पता लगा सकते हैं जहाँ पर उदाहरण अशक्त नहीं होना चाहिए, और यह ठीक से सेट क्यों नहीं है।

उदाहरण

कुछ सामान्य परिदृश्य जहां अपवाद को फेंका जा सकता है:

सामान्य

ref1.ref2.ref3.member

यदि ref1 या ref2 या ref3 शून्य है, तो आपको ए NullReferenceException। यदि आप समस्या को हल करना चाहते हैं, तो यह पता लगाएं कि कौन सा सरल इसके समकक्ष अभिव्यक्ति को फिर से लिखना है:

var r1 = ref1;
var r2 = r1.ref2;
var r3 = r2.ref3;
r3.member

विशेष रूप से, में HttpContext.Current.User.Identity.Name, HttpContext.Currentशून्य हो सकता है, या Userसंपत्ति शून्य हो सकती है, या Identityसंपत्ति शून्य हो सकती है।

अप्रत्यक्ष

public class Person 
{
    public int Age { get; set; }
}
public class Book 
{
    public Person Author { get; set; }
}
public class Example 
{
    public void Foo() 
    {
        Book b1 = new Book();
        int authorAge = b1.Author.Age; // You never initialized the Author property.
                                       // there is no Person to get an Age from.
    }
}

यदि आप बच्चे (व्यक्ति) के अशक्त संदर्भ से बचना चाहते हैं, तो आप इसे माता-पिता (पुस्तक) ऑब्जेक्ट के निर्माता में इनिशियलाइज़ कर सकते हैं।

नेस्टेड ऑब्जेक्ट इनिशियलाइज़र

एक ही नेस्टेड ऑब्जेक्ट इनिशियलाइज़र पर लागू होता है:

Book b1 = new Book 
{ 
   Author = { Age = 45 } 
};

यह करने के लिए अनुवाद

Book b1 = new Book();
b1.Author.Age = 45;

जब newकीवर्ड का उपयोग किया जाता है, तो यह केवल एक नया उदाहरण बनाता है Book, लेकिन एक नया उदाहरण नहीं है Person, इसलिए Authorसंपत्ति अभी भी है null

नेस्टेड संग्रह शुरुआती

public class Person 
{
    public ICollection<Book> Books { get; set; }
}
public class Book 
{
    public string Title { get; set; }
}

नेस्टेड संग्रह Initializersसमान व्यवहार करता है:

Person p1 = new Person 
{
    Books = {
         new Book { Title = "Title1" },
         new Book { Title = "Title2" },
    }
};

यह करने के लिए अनुवाद

Person p1 = new Person();
p1.Books.Add(new Book { Title = "Title1" });
p1.Books.Add(new Book { Title = "Title2" });

new Personकेवल का एक उदाहरण बनाता है Person, लेकिन Booksसंग्रह अब भी है null। संग्रह Initializerसिंटैक्स के लिए एक संग्रह नहीं बनाता है p1.Books, यह केवल अनुवाद करता हैp1.Books.Add(...) बयानों में है।

सरणी

int[] numbers = null;
int n = numbers[0]; // numbers is null. There is no array to index.

ऐरे तत्व

Person[] people = new Person[5];
people[0].Age = 20 // people[0] is null. The array was allocated but not
                   // initialized. There is no Person to set the Age for.

दांतेदार Arrays

long[][] array = new long[1][];
array[0][0] = 3; // is null because only the first dimension is yet initialized.
                 // Use array[0] = new long[2]; first.

संग्रह / सूची / शब्दकोश

Dictionary<string, int> agesForNames = null;
int age = agesForNames["Bob"]; // agesForNames is null.
                               // There is no Dictionary to perform the lookup.

रेंज चर (अप्रत्यक्ष / आस्थगित)

public class Person 
{
    public string Name { get; set; }
}
var people = new List<Person>();
people.Add(null);
var names = from p in people select p.Name;
string firstName = names.First(); // Exception is thrown here, but actually occurs
                                  // on the line above.  "p" is null because the
                                  // first element we added to the list is null.

आयोजन

public class Demo
{
    public event EventHandler StateChanged;

    protected virtual void OnStateChanged(EventArgs e)
    {        
        StateChanged(this, e); // Exception is thrown here 
                               // if no event handlers have been attached
                               // to StateChanged event
    }
}

###Bad Naming Conventions:

If you named fields differently from locals, you might have realized that you never initialized the field. 

सार्वजनिक वर्ग फॉर्म 1 {निजी ग्राहक ग्राहक;

private void Form1_Load(object sender, EventArgs e) 
{
    Customer customer = new Customer();
    customer.Name = "John";
}

private void Button_Click(object sender, EventArgs e)
{
    MessageBox.Show(customer.Name);
}

}

यह एक अंडरस्कोर के साथ उपसर्ग क्षेत्रों के सम्मेलन का पालन करके हल किया जा सकता है:

    private Customer _customer;

ASP.NET पृष्ठ जीवन चक्र:

public partial class Issues_Edit : System.Web.UI.Page
{
    protected TestIssue myIssue;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
             // Only called on first load, not when button clicked
             myIssue = new TestIssue(); 
        }
    }

    protected void SaveButton_Click(object sender, EventArgs e)
    {
        myIssue.Entry = "NullReferenceException here!";
    }
}

ASP.NET सत्र मान

// if the "FirstName" session value has not yet been set,
// then this line will throw a NullReferenceException
string firstName = Session["FirstName"].ToString();

ASP.NET MVC रिक्त दृश्य मॉडल

अपवाद तब होता है जब की संपत्ति को संदर्भित तो @Modelएक में ASP.NET MVC View, आपको यह समझना होगा कि जरूरत है Model, जब आप अपने कार्रवाई विधि में सेट हो जाता है returnएक दृश्य। जब आप अपने नियंत्रक से एक खाली मॉडल (या मॉडल संपत्ति) वापस करते हैं, तो अपवाद तब होता है जब दृश्य इसे एक्सेस करते हैं:

// Controller
public class Restaurant:Controller
{
    public ActionResult Search()
    {
        return View();  // Forgot the provide a Model here.
    }
}

// Razor view 
@foreach (var restaurantSearch in Model.RestaurantSearch)  // Throws.
{
}

<p>@Model.somePropertyName</p> <!-- Also throws -->

WPF कंट्रोल क्रिएशन ऑर्डर और इवेंट्स

WPFनियंत्रण कॉल के दौरान बनाए जाते हैं InitializeComponentताकि वे दृश्य पेड़ में दिखाई दें। NullReferenceExceptionघटना संचालकों, आदि के साथ जल्दी से बनाए गए नियंत्रणों के मामले में ए को उठाया जाएगा, जो आग के दौरान InitializeComponentदेर से बनाए गए नियंत्रणों को संदर्भित करता है।

उदाहरण के लिए :

<Grid>
    <!-- Combobox declared first -->
    <ComboBox Name="comboBox1" 
              Margin="10"
              SelectedIndex="0" 
              SelectionChanged="comboBox1_SelectionChanged">
       <ComboBoxItem Content="Item 1" />
       <ComboBoxItem Content="Item 2" />
       <ComboBoxItem Content="Item 3" />
    </ComboBox>

    <!-- Label declared later -->
    <Label Name="label1" 
           Content="Label"
           Margin="10" />
</Grid>

यहाँ comboBox1पहले बनाया गया है label1। यदि comboBox1_SelectionChanged'लेबल 1' को संदर्भित करने का प्रयास किया जाता है, तो यह अभी तक नहीं बनाया गया है।

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    label1.Content = comboBox1.SelectedIndex.ToString(); // NullReference here!!
}

में घोषणाओं के क्रम को बदलना XAML(यानी, label1पहले से लिस्टिंग comboBox1, डिजाइन दर्शन के मुद्दों की अनदेखी, कम से कम हल होगाNullReferenceException यहां ।

के साथ डाली as

var myThing = someObject as Thing;

यह फेंक नहीं करता है, InvalidCastExceptionलेकिन nullजब कलाकार विफल हो जाता है (और जब someObjectखुद को अशक्त होता है) रिटर्न देता है । तो उस के बारे में पता होना चाहिए।

LINQ FirstOrDefault()औरSingleOrDefault()

सादे संस्करण First()और Single()अपवाद कुछ नहीं होने पर फेंक देते हैं। "OrDefault" संस्करण उस स्थिति में अशक्त हो जाते हैं। तो उस के बारे में पता होना चाहिए।

प्रत्येक के लिए

foreachजब आप अशक्त संग्रह पुनरावृति करने की कोशिश करते हैं तो फेंकता है। आमतौर nullपर संग्रह को वापस करने वाले तरीकों से अप्रत्याशित परिणाम के कारण ।

List<int> list = null;    
foreach(var v in list) { } // exception

अधिक यथार्थवादी उदाहरण - XML ​​दस्तावेज़ से नोड्स का चयन करें। अगर नोड्स नहीं मिले तो फेंक देंगे लेकिन शुरुआती डिबगिंग से पता चलता है कि सभी गुण मान्य हैं:

foreach (var node in myData.MyXml.DocumentNode.SelectNodes("//Data"))

बचने के तरीके

स्पष्ट रूप से जांच करें nullऔर अशक्त मूल्यों की अनदेखी करें।

यदि आप कभी-कभी संदर्भ को शून्य होने की उम्मीद करते हैं, तो आप nullउदाहरण के सदस्यों तक पहुँचने से पहले इसकी जाँच कर सकते हैं:

void PrintName(Person p)
{
    if (p != null) 
    {
        Console.WriteLine(p.Name);
    }
}

nullडिफ़ॉल्ट मान के लिए स्पष्ट रूप से जांचें और प्रदान करें।

विधियाँ कहती हैं कि आप एक उदाहरण लौटाने की अपेक्षा कर सकते हैं null, उदाहरण के लिए जब मांगी जा रही वस्तु नहीं मिल सकती है। जब यह मामला हो तो आप एक डिफ़ॉल्ट मान लौटाना चुन सकते हैं:

string GetCategory(Book b) 
{
    if (b == null)
        return "Unknown";
    return b.Category;
}

nullविधि कॉल से स्पष्ट रूप से जांचें और एक कस्टम अपवाद फेंकें।

आप एक कस्टम अपवाद भी फेंक सकते हैं, केवल इसे कॉलिंग कोड में पकड़ने के लिए:

string GetCategory(string bookTitle) 
{
    var book = library.FindBook(bookTitle);  // This may return null
    if (book == null)
        throw new BookNotFoundException(bookTitle);  // Your custom exception
    return book.Category;
}

Debug.Assertयदि मान कभी नहीं होना चाहिए, तो उपयोग करेंnull अपवाद होने से पहले समस्या को पकड़ने के लिए , ।

जब आप विकास के दौरान जानते हैं कि एक तरीका शायद हो सकता है, लेकिन कभी भी वापस नहीं लौटना चाहिए null, तो आप Debug.Assert()जितनी जल्दी हो सके इसे तोड़ने के लिए उपयोग कर सकते हैं:

string GetTitle(int knownBookID) 
{
    // You know this should never return null.
    var book = library.GetBook(knownBookID);  

    // Exception will occur on the next line instead of at the end of this method.
    Debug.Assert(book != null, "Library didn't return a book for known book ID.");

    // Some other code

    return book.Title; // Will never throw NullReferenceException in Debug mode.
}

हालांकि यह चेक आपके रिलीज़ बिल्ड में समाप्त नहीं होगा , क्योंकि यह रिलीज़ मोड में रनटाइम पर NullReferenceExceptionफिर से फेंक देगा book == null

जब वे होते हैं तो डिफ़ॉल्ट प्रकार प्रदान करने के GetValueOrDefault()लिए nullableमूल्य प्रकारों के लिए उपयोग करें null

DateTime? appointment = null;
Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
// Will display the default value provided (DateTime.Now), because appointment is null.

appointment = new DateTime(2022, 10, 20);
Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
// Will display the appointment date, not the default

अशक्त coalescing ऑपरेटर का उपयोग करें: ??[C #] या If()[VB]।

nullसामने आने पर डिफ़ॉल्ट मान प्रदान करने का आशुलिपि :

IService CreateService(ILogger log, Int32? frobPowerLevel)
{
   var serviceImpl = new MyService(log ?? NullLog.Instance);

   // Note that the above "GetValueOrDefault()" can also be rewritten to use
   // the coalesce operator:
   serviceImpl.FrobPowerLevel = frobPowerLevel ?? 5;
}

अशक्त स्थिति ऑपरेटर का उपयोग करें: ?.या?[x] सरणियों के लिए (C # 6 और VB.NET 14 में उपलब्ध):

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

var title = person.Title.ToUpper();

यदि व्यक्ति के पास शीर्षक नहीं है, तो यह एक अपवाद फेंक देगा क्योंकि यह ToUpperएक शून्य मान के साथ एक संपत्ति पर कॉल करने की कोशिश कर रहा है ।

में C# 5और नीचे, इस के साथ संरक्षित किया जा सकता है:

var title = person.Title == null ? null : person.Title.ToUpper();

अब शीर्षक चर एक अपवाद को फेंकने के बजाय अशक्त होगा। C # 6 इसके लिए एक छोटे वाक्यविन्यास का परिचय देता है:

var title = person.Title?.ToUpper();

इसका परिणाम शीर्षक चर में होगा null, और कॉल ToUpperयदि नहीं किया गया person.Titleहै null

बेशक, आपको अभी भीtitle अशक्त होने के लिए जाँच करना है या अशक्त संचालक के साथ अशक्त संचालक ऑपरेटर का उपयोग करना है ( ??) एक डिफ़ॉल्ट मूल्य की आपूर्ति करने के लिए:

// regular null check
int titleLength = 0;
if (title != null)
    titleLength = title.Length; // If title is null, this would throw NullReferenceException

// combining the `?` and the `??` operator
int titleLength = title?.Length ?? 0;

इसी तरह, सरणियों के लिए आप ?[i]निम्नानुसार उपयोग कर सकते हैं :

int[] myIntArray=null;
var i=5;
int? elem = myIntArray?[i];
if (!elem.HasValue) Console.WriteLine("No value");

यह निम्न कार्य करेगा: यदि myIntArrayअशक्त है, तो अभिव्यक्ति अशक्त है और आप इसे सुरक्षित रूप से जांच सकते हैं। यदि इसमें एक सरणी है, तो यह वैसा ही करेगा: elem = myIntArray[i];और i<sup>th</sup>तत्व को लौटाता है ।

अशक्त संदर्भ का उपयोग करें (C # 8 में उपलब्ध):

C# 8वहाँ अशक्त संदर्भ में प्रस्तुत किया गया है और अशक्त संदर्भ प्रकार वैरिएबल पर स्थिर विश्लेषण करते हैं और एक संकलक चेतावनी प्रदान करते हैं यदि मूल्य संभावित रूप से अशक्त हो सकता है या अशक्त करने के लिए सेट किया गया है। अशक्त संदर्भ प्रकार स्पष्ट रूप से अशक्त होने की अनुमति देता है।

अशक्त एनोटेशन संदर्भ और अशक्त चेतावनी संदर्भ Nullableआपकी csprojफ़ाइल में तत्व का उपयोग करके किसी प्रोजेक्ट के लिए सेट किया जा सकता है । यह तत्व कॉन्फ़िगर करता है कि कंपाइलर किस प्रकार की अशक्तता की व्याख्या करता है और क्या चेतावनी उत्पन्न करता है। मान्य सेटिंग्स हैं:

  • सक्षम: अशक्त एनोटेशन संदर्भ सक्षम है। अशक्त चेतावनी संदर्भ सक्षम है। एक संदर्भ प्रकार के चर, उदाहरण के लिए स्ट्रिंग, गैर-अशक्त हैं। सभी अशक्तता चेतावनी सक्षम हैं।
  • अक्षम: अशक्त एनोटेशन संदर्भ अक्षम है। अशक्त चेतावनी संदर्भ अक्षम है। एक संदर्भ प्रकार के चर, C # के पुराने संस्करणों की तरह ही अनजान हैं। सभी अशक्तता चेतावनी अक्षम हैं।
  • सुरक्षित रूप से: अशक्त एनोटेशन संदर्भ सक्षम है। अशक्त चेतावनी संदर्भ सुरक्षित है। एक संदर्भ प्रकार के चर अमानवीय हैं। सभी सुरक्षा अशक्तता चेतावनी सक्षम हैं।
  • चेतावनी: अशक्त एनोटेशन संदर्भ अक्षम है। अशक्त चेतावनी संदर्भ सक्षम है। एक संदर्भ प्रकार के चर गुमनामी हैं। सभी अशक्तता चेतावनी सक्षम हैं।
  • safeonlywarnings: अशक्त एनोटेशन संदर्भ अक्षम है। अशक्त चेतावनी संदर्भ सुरक्षित है। एक संदर्भ प्रकार के चर गुमनामी हैं। सभी सुरक्षा अशक्तता चेतावनी सक्षम हैं।

एक अशक्त संदर्भ प्रकार को शून्य मान के प्रकार के समान सिंटैक्स का उपयोग करके नोट किया जाता है: एक ?चर के प्रकार से जोड़ा जाता है।

डिबगिंग और नलकूपों को ठीक करने की विशेष तकनीकें पुनरावृत्तियों में

C#"इटरेटर ब्लॉक" (कुछ अन्य लोकप्रिय भाषाओं में "जनरेटर") का समर्थन करता है। आस्थगित निष्पादन के कारण इटैलर ब्लॉकों में डिबगिंग अपवाद विशेष रूप से कमजोर हो सकते हैं:

public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
    for (int i = 0; i < count; ++i)
    yield return f.MakeFrob();
}
...
FrobFactory factory = whatever;
IEnumerable<Frobs> frobs = GetFrobs();
...
foreach(Frob frob in frobs) { ... }

अगर whateverपरिणाम में है nullतो MakeFrobफेंक देंगे। अब, आप सोच सकते हैं कि ऐसा करना सही है:

// DON'T DO THIS
public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
   if (f == null) 
      throw new ArgumentNullException("f", "factory must not be null");
   for (int i = 0; i < count; ++i)
      yield return f.MakeFrob();
}

यह गलत क्यों है? क्योंकि इटरेटर ब्लॉक वास्तव में तब तक नहीं चलता है जब तक foreach! कॉल GetFrobsकेवल एक वस्तु को लौटाता है जो पुनरावृत्त होने पर पुनरावृत्त ब्लॉक को चलाएगा।

इस तरह एक अशक्त चेक लिखने से आप अशक्तता को रोकते हैं, लेकिन आप अशक्त तर्क अपवाद को पुनरावृत्ति के बिंदु पर ले जाते हैं , कॉल के बिंदु तक नहीं , और यह डीबग करने के लिए बहुत भ्रामक है

सही फिक्स है:

// DO THIS
public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
   // No yields in a public method that throws!
   if (f == null) 
       throw new ArgumentNullException("f", "factory must not be null");
   return GetFrobsForReal(f, count);
}
private IEnumerable<Frob> GetFrobsForReal(FrobFactory f, int count)
{
   // Yields in a private method
   Debug.Assert(f != null);
   for (int i = 0; i < count; ++i)
        yield return f.MakeFrob();
}

यही है, एक निजी सहायक विधि बनाओ जिसमें इट्रेटर ब्लॉक लॉजिक है, और एक सार्वजनिक सतह विधि है जो अशक्त जांच करता है और पुनरावृत्तिकर्ता को लौटाता है। अब जब GetFrobsबुलाया जाता है, तो नल की जांच तुरंत होती है, और फिर GetFrobsForRealअनुक्रम के पुनरावृत्त होने पर निष्पादित होता है।

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

असुरक्षित कोड में अशक्त डीरेफरेंस पर एक नोट

C#एक "असुरक्षित" मोड है, जो नाम का अर्थ है, अत्यंत खतरनाक है क्योंकि सामान्य सुरक्षा तंत्र जो स्मृति सुरक्षा और प्रकार की सुरक्षा प्रदान करते हैं, लागू नहीं होते हैं। जब तक आपके पास मेमोरी काम नहीं करती है, तब तक आपको असुरक्षित कोड नहीं लिखना चाहिए

असुरक्षित मोड में, आपको दो महत्वपूर्ण तथ्यों की जानकारी होनी चाहिए:

  • एक अशक्त सूचक को dereferencing एक शून्य संदर्भ dereferencing के रूप में एक ही अपवाद पैदा करता है
  • अमान्य नॉन-नेल पॉइंटर को डीफ़ेरिंग करना कुछ परिस्थितियों में उस अपवाद को उत्पन्न कर सकता है

यह समझने के लिए कि यह क्यों है, यह समझने में मदद करता है कि .NET पहली बार में शून्य से अधिक अपवाद कैसे पैदा करता है। (ये विवरण विंडोज़ पर चलने वाले .NET पर लागू होते हैं; अन्य ऑपरेटिंग सिस्टम समान तंत्र का उपयोग करते हैं।)

स्मृति का आभासीकरण किया जाता है Windows; प्रत्येक प्रक्रिया को मेमोरी के कई "पेज" का वर्चुअल मेमोरी स्पेस मिलता है जो ऑपरेटिंग सिस्टम द्वारा ट्रैक किया जाता है। स्मृति के प्रत्येक पृष्ठ पर झंडे सेट होते हैं जो यह निर्धारित करते हैं कि इसका उपयोग कैसे किया जा सकता है: से पढ़ा, लिखा, निष्पादित किया गया, और इसी तरह। सबसे कम पृष्ठ को "किसी भी तरह से उपयोग किए जाने पर त्रुटि उत्पन्न करना" के रूप में चिह्नित किया गया है।

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

यही कारण है कि दोनों एक अशक्त सूचक और एक शून्य संदर्भ दोनों को एक ही अपवाद पैदा करता है।

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

यह क्यों समझ में आता है? ठीक है, मान लें कि हमारे पास एक संरचना है जिसमें दो ints, और एक अशक्त सूचक शून्य के बराबर है। यदि हम संरचना में दूसरे इंट को दखल देने का CLRप्रयास करते हैं, तो स्थान शून्य पर भंडारण का उपयोग करने का प्रयास नहीं करेंगे; यह स्टोरेज को स्थान चार पर पहुँचा देगा। लेकिन तार्किक रूप से यह एक अशांति है क्योंकि हम अशक्त के माध्यम से उस पते पर जा रहे हैं ।

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


55
हो सकता है कि यह एक विनम्र टिप्पणी हो लेकिन इस समस्या से बचने का पहला और सबसे अच्छा तरीका यह होगा कि वस्तु को इनिशियलाइज़ किया जाए? मेरे लिए अगर यह त्रुटि होती है तो यह आमतौर पर होता है क्योंकि मैं एरे तत्व की तरह कुछ को इनिशियलाइज़ करना भूल गया था। मुझे लगता है कि वस्तु को शून्य के रूप में परिभाषित करना और फिर इसे संदर्भित करना बहुत कम आम है। शायद विवरण से सटे प्रत्येक समस्या को हल करने का तरीका दें। फिर भी एक अच्छी पोस्ट।
जेपीके

30
क्या होगा यदि कोई वस्तु नहीं है, बल्कि एक विधि या संपत्ति से वापसी मूल्य है?
जॉन सॉन्डर्स

6
पुस्तक / लेखक का उदाहरण थोड़ा अजीब है .... यह भी कैसे संकलन करता है? इंटेलीजेंस भी कैसे काम करता है? क्या है यह मैं

5
@Will: क्या मेरा अंतिम संपादन मदद करता है? यदि नहीं, तो कृपया एक समस्या के रूप में जो आप देखते हैं उसके बारे में अधिक स्पष्ट हो।
जॉन सॉन्डर्स

6
@ जॉनसनर्स ओह, नहीं, क्षमा करें, मेरा मतलब था कि उस वस्तु का शुरुआती संस्करण। new Book { Author = { Age = 45 } };भीतर का इनिशियलाइज़ेशन भी कैसे होता है ... मैं ऐसी स्थिति के बारे में नहीं सोच सकता, जहाँ भीतर का काम कभी चलेगा, फिर भी यह काम करता है और अंतर्मुखी काम करता है ... जब तक कि यह संरचना के लिए न हो?

311

NullReference अपवाद - विज़ुअल बेसिक

NullReference Exceptionके लिए दृश्य मूल में एक से अलग नहीं है सी # । आखिरकार, वे दोनों .NET फ्रेमवर्क में परिभाषित एक ही अपवाद को रिपोर्ट कर रहे हैं जो वे दोनों का उपयोग करते हैं। Visual Basic के लिए अद्वितीय कारण दुर्लभ हैं (शायद केवल एक)।

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

ध्यान दें:

  1. यह अवधारणा-आधारित है: आपके पास अपनी परियोजना में पेस्ट करने के लिए कोई कोड नहीं है। इसका उद्देश्य आपको यह समझने में मदद करना है कि क्या कारण है NullReferenceException(एनआरई), इसे कैसे खोजना है, इसे कैसे ठीक करना है और कैसे इससे बचना है। एक एनआरई कई तरीकों से हो सकता है इसलिए यह आपके एकमात्र मुठभेड़ होने की संभावना नहीं है।
  2. उदाहरण (स्टैक ओवरफ्लो पोस्ट से) हमेशा पहली जगह में कुछ करने का सबसे अच्छा तरीका नहीं दिखाते हैं।
  3. आमतौर पर, सबसे सरल उपाय का उपयोग किया जाता है।

मूल अर्थ

संदेश "ऑब्जेक्ट ऑब्जेक्ट के एक उदाहरण के लिए सेट नहीं है" का अर्थ है कि आप उस ऑब्जेक्ट का उपयोग करने की कोशिश कर रहे हैं जिसे प्रारंभ नहीं किया गया है। यह इनमें से एक को उबालता है:

  • आपके कोड ने एक वस्तु चर घोषित किया , लेकिन उसने इसे इनिशियलाइज़ नहीं किया (एक उदाहरण बनाएं या इसे ' तत्काल ' बनाएं )
  • कुछ ऐसा है जो आपके कोड ने मान लिया कि किसी ऑब्जेक्ट को इनिशियलाइज़ करेगा, नहीं
  • संभवतः, अन्य कोड ने समय से पहले एक वस्तु को अवैध रूप से अमान्य कर दिया है

कारण ढूँढना

चूंकि समस्या एक वस्तु संदर्भ है Nothing, जो है , इसका उत्तर यह है कि उन्हें यह पता लगाने के लिए कि कौन सा है। फिर निर्धारित करें कि यह क्यों प्रारंभिक नहीं है। विभिन्न चर पर माउस को पकड़ें और विजुअल स्टूडियो (वीएस) अपने मूल्यों को दिखाएगा - अपराधी होगा Nothing

आईडीई डिबग डिस्प्ले

आपको संबंधित कोड से किसी भी कोशिश / कैच ब्लॉक को भी हटा देना चाहिए, खासकर उन लोगों को जहां कैच ब्लॉक में कुछ भी नहीं है। जब यह किसी ऑब्जेक्ट का उपयोग करने का प्रयास करता है तो यह आपके कोड को क्रैश कर देगा Nothingयह वही है जो आप चाहते हैं क्योंकि यह समस्या के सटीक स्थान की पहचान करेगा , और आपको इसके कारण होने वाली वस्तु की पहचान करने की अनुमति देगा।

MsgBoxपकड़ में A जो प्रदर्शित करता है उससे Error while...बहुत कम मदद मिलेगी। यह विधि बहुत खराब स्टैक ओवरफ्लो प्रश्नों की ओर भी ले जाती है , क्योंकि आप वास्तविक अपवाद, शामिल वस्तु या यहां तक ​​कि कोड की पंक्ति का वर्णन नहीं कर सकते हैं जहां यह होता है।

आप अपनी वस्तुओं की जांच करने के लिए Locals Window( डिबग -> विंडोज -> स्थानीय लोगों ) का भी उपयोग कर सकते हैं।

एक बार जब आप जानते हैं कि समस्या क्या है और कहां है, तो आमतौर पर एक नया प्रश्न पोस्ट करने की तुलना में इसे ठीक करना और तेज करना काफी आसान है।

यह सभी देखें:

उदाहरण और उपाय

कक्षा वस्तुओं / एक उदाहरण बनाना

Dim reg As CashRegister
...
TextBox1.Text = reg.Amount         ' NRE

समस्या यह है कि Dimएक CashRegister ऑब्जेक्ट नहीं बनाता है ; यह केवल regउस प्रकार के नाम से एक चर घोषित करता है । ऑब्जेक्ट चर की घोषणा करना और एक उदाहरण बनाना दो अलग-अलग चीजें हैं।

उपाय

Newऑपरेटर अक्सर जब आप इसे घोषित उदाहरण बनाने के लिए इस्तेमाल किया जा सकता है:

Dim reg As New CashRegister        ' [New] creates instance, invokes the constructor

' Longer, more explicit form:
Dim reg As CashRegister = New CashRegister

जब बाद में उदाहरण बनाना ही उचित हो:

Private reg As CashRegister         ' Declare
  ...
reg = New CashRegister()            ' Create instance

नोट: निर्माणकर्ता ( ) सहित एक प्रक्रिया में फिर से उपयोग करें :DimSub New

Private reg As CashRegister
'...

Public Sub New()
   '...
   Dim reg As New CashRegister
End Sub

यह एक स्थानीय चर बनाएगा reg, जो केवल उस संदर्भ (उप) में मौजूद है। regमॉड्यूल स्तर के साथ चर Scopeजो आप अन्य सभी स्थानों अवशेष का उपयोग करेगा Nothing

Newऑपरेटर को मिस करनाNullReference Exceptions स्टैक ओवरफ्लो प्रश्नों की समीक्षा में देखा गया # 1 कारण है

Visual Basic का उपयोग करके प्रक्रिया को बार-बार स्पष्ट करने की कोशिश करता है New: Newऑपरेटर का उपयोग करना एक बनाता है नई वस्तु बनती है और कॉल होती है Sub New- निर्माणकर्ता - जहाँ आपकी वस्तु किसी अन्य इनिशियलाइज़ेशन को कर सकती है।

स्पष्ट होने के लिए, Dim(या Private) केवल एक चर और इसकी घोषणा करता है Type। चर का दायरा - चाहे वह पूरे मॉड्यूल / वर्ग के लिए मौजूद हो या प्रक्रिया के लिए स्थानीय हो - द्वारा निर्धारित किया जाता है कि यह कहां घोषित किया गया है। Private | Friend | Publicपहुँच स्तर को परिभाषित करता है, स्कोप को नहीं ।

अधिक जानकारी के लिए देखें:


Arrays

Arrays को भी तत्काल किया जाना चाहिए:

Private arr as String()

यह सरणी केवल घोषित की गई है, बनाई नहीं गई है। किसी सरणी को आरम्भ करने के कई तरीके हैं:

Private arr as String() = New String(10){}
' or
Private arr() As String = New String(10){}

' For a local array (in a procedure) and using 'Option Infer':
Dim arr = New String(10) {}

नोट: वीएस 2010 के साथ शुरुआत, जब एक स्थानीय सरणी को शाब्दिक और तत्वों का उपयोग करके आरम्भ किया जाता है Option Infer, As <Type>और Newतत्व वैकल्पिक हैं:

Dim myDbl As Double() = {1.5, 2, 9.9, 18, 3.14}
Dim myDbl = New Double() {1.5, 2, 9.9, 18, 3.14}
Dim myDbl() = {1.5, 2, 9.9, 18, 3.14}

डेटा प्रकार और सरणी आकार असाइन किए जा रहे डेटा से अनुमानित हैं। कक्षा / मॉड्यूल स्तर की घोषणाओं की अभी भी आवश्यकता As <Type>है Option Strict:

Private myDoubles As Double() = {1.5, 2, 9.9, 18, 3.14}

उदाहरण: वर्ग की वस्तुओं की सरणी

Dim arrFoo(5) As Foo

For i As Integer = 0 To arrFoo.Count - 1
   arrFoo(i).Bar = i * 10       ' Exception
Next

सरणी बनाई गई है, लेकिन इसमें Fooऑब्जेक्ट नहीं हैं।

उपाय

For i As Integer = 0 To arrFoo.Count - 1
    arrFoo(i) = New Foo()         ' Create Foo instance
    arrFoo(i).Bar = i * 10
Next

एक का उपयोग करना एक List(Of T)वैध वस्तु के बिना एक तत्व रखना काफी मुश्किल होगा:

Dim FooList As New List(Of Foo)     ' List created, but it is empty
Dim f As Foo                        ' Temporary variable for the loop

For i As Integer = 0 To 5
    f = New Foo()                    ' Foo instance created
    f.Bar =  i * 10
    FooList.Add(f)                   ' Foo object added to list
Next

अधिक जानकारी के लिए देखें:


सूचियाँ और संग्रह

.NET संग्रह (जिनमें से कई किस्में हैं - सूची, शब्दकोश, आदि) को भी तत्काल या बनाया जाना चाहिए।

Private myList As List(Of String)
..
myList.Add("ziggy")           ' NullReference

आपको एक ही कारण के लिए एक ही अपवाद मिलता है - myListकेवल घोषित किया गया था, लेकिन कोई उदाहरण नहीं बनाया गया। उपाय एक ही है:

myList = New List(Of String)

' Or create an instance when declared:
Private myList As New List(Of String)

एक सामान्य निरीक्षण एक वर्ग है जो एक संग्रह का उपयोग करता है Type:

Public Class Foo
    Private barList As List(Of Bar)

    Friend Function BarCount As Integer
        Return barList.Count
    End Function

    Friend Sub AddItem(newBar As Bar)
        If barList.Contains(newBar) = False Then
            barList.Add(newBar)
        End If
    End Function

या तो प्रक्रिया एक एनआरई में परिणाम करेगी, क्योंकि barListकेवल घोषित की जाती है, तात्कालिक नहीं। का एक उदाहरण Fooबनाने से भी आंतरिक का एक उदाहरण नहीं होगा barList। कंस्ट्रक्टर में ऐसा करने का इरादा हो सकता है:

Public Sub New         ' Constructor
    ' Stuff to do when a new Foo is created...
    barList = New List(Of Bar)
End Sub

पहले की तरह, यह गलत है:

Public Sub New()
    ' Creates another barList local to this procedure
     Dim barList As New List(Of Bar)
End Sub

अधिक जानकारी के लिए, List(Of T)क्लास देखें ।


डेटा प्रदाता ऑब्जेक्ट

डेटाबेस प्रस्तुत के साथ एक NullReference के लिए कई अवसर कार्य क्योंकि वहाँ कई वस्तुओं (हो सकता है Command, Connection, Transaction, Dataset, DataTable, DataRowsएक ही बार में ....) उपयोग में। नोट: यह कोई फर्क नहीं पड़ता कि आप किस डेटा प्रदाता का उपयोग कर रहे हैं - MySQL, SQL सर्वर, OleDB, आदि - अवधारणाएं समान हैं।

उदाहरण 1

Dim da As OleDbDataAdapter
Dim ds As DataSet
Dim MaxRows As Integer

con.Open()
Dim sql = "SELECT * FROM tblfoobar_List"
da = New OleDbDataAdapter(sql, con)
da.Fill(ds, "foobar")
con.Close()

MaxRows = ds.Tables("foobar").Rows.Count      ' Error

पहले की तरह, dsडेटासेट ऑब्जेक्ट घोषित किया गया था, लेकिन एक उदाहरण कभी नहीं बनाया गया था। DataAdapterएक मौजूदा भर जाएगा DataSet, नहीं एक बनाएँ। इस मामले में, चूंकि dsएक स्थानीय चर है, आईडीई आपको चेतावनी देता है कि ऐसा हो सकता है:

img

जब मॉड्यूल / वर्ग स्तर के चर के रूप में घोषित किया जाता है, जैसा कि मामला प्रतीत होता है con, तो कंपाइलर को पता नहीं चल सकता है कि ऑब्जेक्ट अपस्ट्रीम प्रक्रिया द्वारा बनाया गया था या नहीं। चेतावनियों को नजरअंदाज न करें।

उपाय

Dim ds As New DataSet

उदाहरण 2

ds = New DataSet
da = New OleDBDataAdapter(sql, con)
da.Fill(ds, "Employees")

txtID.Text = ds.Tables("Employee").Rows(0).Item(1)
txtID.Name = ds.Tables("Employee").Rows(0).Item(2)

एक टाइपो यहाँ एक समस्या है: Employeesबनाम Employee। कोई DataTable"कर्मचारी" नहीं बनाया गया था, इसलिए NullReferenceExceptionइसके उपयोग की कोशिश करने वाले परिणाम। एक अन्य संभावित समस्या यह मानकर चल रही है कि Itemsऐसा तब नहीं होगा जब SQL में WHERE क्लॉज शामिल हो।

उपाय

चूंकि यह एक तालिका का उपयोग करता है, इसलिए Tables(0)स्पेलिंग त्रुटियों से बचना होगा। जांच से Rows.Countभी मदद मिल सकती है:

If ds.Tables(0).Rows.Count > 0 Then
    txtID.Text = ds.Tables(0).Rows(0).Item(1)
    txtID.Name = ds.Tables(0).Rows(0).Item(2)
End If

Fillएक ऐसा कार्य है Rowsजो प्रभावितों की संख्या को लौटाता है जिसे परीक्षण भी किया जा सकता है:

If da.Fill(ds, "Employees") > 0 Then...

उदाहरण 3

Dim da As New OleDb.OleDbDataAdapter("SELECT TICKET.TICKET_NO,
        TICKET.CUSTOMER_ID, ... FROM TICKET_RESERVATION AS TICKET INNER JOIN
        FLIGHT_DETAILS AS FLIGHT ... WHERE [TICKET.TICKET_NO]= ...", con)
Dim ds As New DataSet
da.Fill(ds)

If ds.Tables("TICKET_RESERVATION").Rows.Count > 0 Then

DataAdapterप्रदान करेगा TableNamesजैसा कि पिछले उदाहरण में दिखाया गया है, लेकिन यह एसक्यूएल या डेटाबेस तालिका से नहीं है पार्स नाम। नतीजतन,ds.Tables("TICKET_RESERVATION") एक गैर-मौजूद तालिका का संदर्भ देता है।

उपचार ही है, सूचकांक द्वारा तालिका को देख:

If ds.Tables(0).Rows.Count > 0 Then

डेटाटेबल क्लास भी देखें ।


ऑब्जेक्ट पथ / नेस्टेड

If myFoo.Bar.Items IsNot Nothing Then
   ...

कोड केवल परीक्षण कर रहा है Itemsजबकि दोनों myFooऔर Barकुछ भी नहीं हो सकता है। उपाय एक बार में पूरी श्रृंखला या वस्तुओं में से एक का पथ का परीक्षण करने के लिए है:

If (myFoo IsNot Nothing) AndAlso
    (myFoo.Bar IsNot Nothing) AndAlso
    (myFoo.Bar.Items IsNot Nothing) Then
    ....

AndAlsoमहत्वपूर्ण है। पहली Falseस्थिति सामने आने के बाद बाद के परीक्षण नहीं किए जाएंगे । यह कोड को एक बार में ऑब्जेक्ट (ओं) में सुरक्षित रूप से 'ड्रिल' करने की अनुमति देता है, myFoo.Barकेवल (और अगर) के मूल्यांकन के बाद ही myFooमान्य होता है। जटिल ऑब्जेक्ट्स को कोड करते समय ऑब्जेक्ट चेन या पाथ काफी लंबा मिल सकता है:

myBase.myNodes(3).Layer.SubLayer.Foo.Files.Add("somefilename")

किसी nullवस्तु के 'डाउनस्ट्रीम' को संदर्भित करना संभव नहीं है । यह नियंत्रणों पर भी लागू होता है:

myWebBrowser.Document.GetElementById("formfld1").InnerText = "some value"

यहाँ, myWebBrowserया Documentकुछ भी नहीं हो सकता है या formfld1तत्व मौजूद नहीं हो सकता है।


यूआई नियंत्रण

Dim cmd5 As New SqlCommand("select Cartons, Pieces, Foobar " _
     & "FROM Invoice where invoice_no = '" & _
     Me.ComboBox5.SelectedItem.ToString.Trim & "' And category = '" & _
     Me.ListBox1.SelectedItem.ToString.Trim & "' And item_name = '" & _
     Me.ComboBox2.SelectedValue.ToString.Trim & "' And expiry_date = '" & _
     Me.expiry.Text & "'", con)

अन्य बातों के अलावा, यह कोड यह अनुमान नहीं लगाता है कि उपयोगकर्ता ने एक या अधिक यूआई नियंत्रण में कुछ का चयन नहीं किया होगा। ListBox1.SelectedItemअच्छी तरह से हो सकता है Nothing, इसलिए ListBox1.SelectedItem.ToStringएक एनआरई में परिणाम होगा।

उपाय

उपयोग करने से पहले डेटा को मान्य करें (उपयोग Option Strictऔर SQL पैरामीटर भी):

Dim expiry As DateTime         ' for text date validation
If (ComboBox5.SelectedItems.Count > 0) AndAlso
    (ListBox1.SelectedItems.Count > 0) AndAlso
    (ComboBox2.SelectedItems.Count > 0) AndAlso
    (DateTime.TryParse(expiry.Text, expiry) Then

    '... do stuff
Else
    MessageBox.Show(...error message...)
End If

वैकल्पिक रूप से, आप उपयोग कर सकते हैं (ComboBox5.SelectedItem IsNot Nothing) AndAlso...


विजुअल बेसिक फॉर्म

Public Class Form1

    Private NameBoxes = New TextBox(5) {Controls("TextBox1"), _
                   Controls("TextBox2"), Controls("TextBox3"), _
                   Controls("TextBox4"), Controls("TextBox5"), _
                   Controls("TextBox6")}

    ' same thing in a different format:
    Private boxList As New List(Of TextBox) From {TextBox1, TextBox2, TextBox3 ...}

    ' Immediate NRE:
    Private somevar As String = Me.Controls("TextBox1").Text

यह एनआरई पाने का एक काफी सामान्य तरीका है। C # में, यह कैसे कोडित है, इसके आधार पर, IDE रिपोर्ट करेगा Controlsजो वर्तमान संदर्भ में मौजूद नहीं है, या "गैर-स्थिर सदस्य का संदर्भ नहीं दे सकता है"। तो, कुछ हद तक, यह एक VB- केवल स्थिति है। यह भी जटिल है क्योंकि यह एक विफलता कैस्केड के परिणामस्वरूप हो सकता है।

सरणियों और संग्रह को इस तरह से आरंभ नहीं किया जा सकता है। यह इनिशियलाइज़ेशन कोड कंस्ट्रक्टर या बनाने से पहले चलेगा । नतीजतन:FormControls

  • सूची और संग्रह बस खाली हो जाएगा
  • ऐरे में नथिंग के पांच तत्व होंगे
  • somevarकाम एक तत्काल एनआरई में परिणाम होगा क्योंकि कुछ भी नहीं है एक भी नहीं है .Textसंपत्ति

बाद में सरणी तत्वों को संदर्भित करने से NRE हो जाएगा। यदि आप ऐसा करते हैं Form_Load, तो एक विषम बग के कारण, IDE अपवाद तब नहीं हो सकता जब यह होता है। जब आपका कोड सरणी का उपयोग करने का प्रयास करता है तो अपवाद बाद में पॉप जाएगा । यह "मूक अपवाद" इस पोस्ट में विस्तृत है । हमारे उद्देश्यों के लिए, कुंजी यह है कि जब एक फॉर्म ( Sub Newया Form Loadईवेंट) बनाते समय कुछ भयावह होता है , तो अपवाद अप्रमाणित हो सकते हैं, कोड प्रक्रिया से बाहर निकलता है और बस फॉर्म प्रदर्शित करता है।

चूंकि एनआरई के बाद आपके Sub Newया Form Loadईवेंट में कोई अन्य कोड नहीं चलेगा, इसलिए बहुत सी अन्य चीजों को अनइंस्टॉल किया जा सकता है।

Sub Form_Load(..._
   '...
   Dim name As String = NameBoxes(2).Text        ' NRE
   ' ...
   ' More code (which will likely not be executed)
   ' ...
End Sub

ध्यान दें कि यह किसी भी और सभी नियंत्रण और घटक संदर्भों पर लागू होता है, जहां ये अवैध हैं:

Public Class Form1

    Private myFiles() As String = Me.OpenFileDialog1.FileName & ...
    Private dbcon As String = OpenFileDialog1.FileName & ";Jet Oledb..."
    Private studentName As String = TextBox13.Text

आंशिक उपाय

यह उत्सुक है कि वीबी एक चेतावनी प्रदान नहीं करता है, लेकिन उपाय कंटेनरों को फॉर्म स्तर पर घोषित करना है, लेकिन नियंत्रण के मौजूद होने पर उन्हें लोड लोड ईवेंट हैंडलर में आरंभ करना है। यह तब तक किया जा सकता है Sub Newजब तक आपका कोड InitializeComponentकॉल के बाद है :

' Module level declaration
Private NameBoxes as TextBox()
Private studentName As String

' Form Load, Form Shown or Sub New:
'
' Using the OP's approach (illegal using OPTION STRICT)
NameBoxes = New TextBox() {Me.Controls("TextBox1"), Me.Controls("TestBox2"), ...)
studentName = TextBox32.Text           ' For simple control references

सरणी कोड अभी तक जंगल से बाहर नहीं हो सकता है। कोई भी नियंत्रण जो कंटेनर नियंत्रण में है (जैसे GroupBoxया Panel) में नहीं मिलेगा Me.Controls; वे उस पैनल या GroupBox के नियंत्रण संग्रह में होंगे। जब नियंत्रण नाम गलत वर्तनी ( "TeStBox2") है, तो कोई नियंत्रण वापस नहीं किया जाएगा । ऐसे मामलों में, Nothingफिर से उन सरणी तत्वों में संग्रहीत किया जाएगा और जब आप इसे संदर्भित करने का प्रयास करेंगे तो एक एनआरई परिणाम देगा।

इन्हें ढूंढना आसान होना चाहिए ताकि आप जान सकें कि आप क्या देख रहे हैं: वीएस आपको अपने तरीकों की त्रुटि दिखाता है

"Button2" एक पर रहता है Panel

उपाय

प्रपत्र के Controlsसंग्रह का उपयोग करके नाम के अप्रत्यक्ष संदर्भों के बजाय , नियंत्रण संदर्भ का उपयोग करें:

' Declaration
Private NameBoxes As TextBox()

' Initialization -  simple and easy to read, hard to botch:
NameBoxes = New TextBox() {TextBox1, TextBox2, ...)

' Initialize a List
NamesList = New List(Of TextBox)({TextBox1, TextBox2, TextBox3...})
' or
NamesList = New List(Of TextBox)
NamesList.AddRange({TextBox1, TextBox2, TextBox3...})

फंक्शन रिटर्निंग नथिंग

Private bars As New List(Of Bars)        ' Declared and created

Public Function BarList() As List(Of Bars)
    bars.Clear
    If someCondition Then
        For n As Integer = 0 to someValue
            bars.Add(GetBar(n))
        Next n
    Else
        Exit Function
    End If

    Return bars
End Function

यह एक ऐसा मामला है जहां आईडीई आपको चेतावनी देगा कि ' सभी रास्तों का एक मूल्य और एक NullReferenceExceptionपरिणाम नहीं हो सकता है '। आप चेतावनी को दबा सकते हैं, के Exit Functionसाथ प्रतिस्थापित करके Return Nothing, लेकिन यह समस्या का समाधान नहीं करता है। कुछ भी जो someCondition = Falseएनआरई में परिणाम देगा जब वापसी का उपयोग करने की कोशिश करता है :

bList = myFoo.BarList()
For Each b As Bar in bList      ' EXCEPTION
      ...

उपाय

के Exit Functionसाथ फ़ंक्शन में बदलें Return bListखाली लौटना Listवैसा ही नहीं है जैसा लौटना Nothing। यदि एक मौका है कि एक लौटी हुई वस्तु हो सकती है Nothing, तो उपयोग करने से पहले परीक्षण करें:

 bList = myFoo.BarList()
 If bList IsNot Nothing Then...

खराब रूप से लागू किया गया प्रयास / कैच

एक बुरी तरह से कार्यान्वित किया गया प्रयास / कैच छिपा सकता है जहां समस्या है और नए परिणाम हैं:

Dim dr As SqlDataReader
Try
    Dim lnk As LinkButton = TryCast(sender, LinkButton)
    Dim gr As GridViewRow = DirectCast(lnk.NamingContainer, GridViewRow)
    Dim eid As String = GridView1.DataKeys(gr.RowIndex).Value.ToString()
    ViewState("username") = eid
    sqlQry = "select FirstName, Surname, DepartmentName, ExtensionName, jobTitle,
             Pager, mailaddress, from employees1 where username='" & eid & "'"
    If connection.State <> ConnectionState.Open Then
        connection.Open()
    End If
    command = New SqlCommand(sqlQry, connection)

    'More code fooing and barring

    dr = command.ExecuteReader()
    If dr.Read() Then
        lblFirstName.Text = Convert.ToString(dr("FirstName"))
        ...
    End If
    mpe.Show()
Catch

Finally
    command.Dispose()
    dr.Close()             ' <-- NRE
    connection.Close()
End Try

यह एक ऐसी वस्तु का मामला है जिसे अपेक्षित रूप से नहीं बनाया जा रहा है, लेकिन यह खाली की काउंटर उपयोगिता को भी प्रदर्शित करता है Catch

SQL में एक अतिरिक्त अल्पविराम है ('mailaddress' के बाद) जिसके परिणामस्वरूप इसका अपवाद है .ExecuteReader। बाद Catchकुछ नहीं करता, Finallyस्वच्छ ऊपर प्रदर्शन करने की कोशिश करता है, लेकिन जब से तुम नहीं कर सकते हैं Closeएक अशक्त DataReaderवस्तु, एक नया NullReferenceExceptionपरिणाम नहीं।

एक खाली Catchब्लॉक शैतान का खेल का मैदान है। इस ओपी को चकित किया गया कि वह Finallyब्लॉक में एनआरई क्यों बन रहा है । अन्य स्थितियों में, एक खाली Catchचीज के परिणामस्वरूप कुछ और बहाव हो सकता है और आप समस्या के लिए गलत जगह पर गलत चीजों को देखने में समय व्यतीत कर सकते हैं। (ऊपर वर्णित "मूक अपवाद" वही मनोरंजन मूल्य प्रदान करता है।)

उपाय

खाली का उपयोग न करें कोशिश करें / पकड़ ब्लॉक - कोड को क्रैश होने दें ताकि आप ए) कारण की पहचान कर सकें बी) स्थान की पहचान करें और सी) एक उचित उपाय लागू करें। डेवलपर को पकड़ने के लिए प्रयास / कैच ब्लॉक का उद्देश्य विशिष्ट रूप से योग्य व्यक्ति से अपवादों को छिपाना नहीं है।


DBNull कुछ भी नहीं के समान नहीं है

For Each row As DataGridViewRow In dgvPlanning.Rows
    If Not IsDBNull(row.Cells(0).Value) Then
        ...

IsDBNullसमारोह परीक्षण करने के लिए इस्तेमाल करता है, तो एक है मूल्य के बराबर होती है System.DBNull: MSDN से:

System.DBNull मान इंगित करता है कि ऑब्जेक्ट गुम या गैर-मौजूद डेटा का प्रतिनिधित्व करता है। DBNull कुछ भी नहीं के समान नहीं है, जो इंगित करता है कि एक चर अभी तक आरंभ नहीं किया गया है।

उपाय

If row.Cells(0) IsNot Nothing Then ...

पहले की तरह, आप कुछ भी नहीं के लिए परीक्षण कर सकते हैं, फिर एक विशिष्ट मूल्य के लिए:

If (row.Cells(0) IsNot Nothing) AndAlso (IsDBNull(row.Cells(0).Value) = False) Then

उदाहरण 2

Dim getFoo = (From f In dbContext.FooBars
               Where f.something = something
               Select f).FirstOrDefault

If Not IsDBNull(getFoo) Then
    If IsDBNull(getFoo.user_id) Then
        txtFirst.Text = getFoo.first_name
    Else
       ...

FirstOrDefaultपहला आइटम या डिफ़ॉल्ट मान लौटाता है, जो Nothingसंदर्भ प्रकारों के लिए है और कभी नहीं DBNull:

If getFoo IsNot Nothing Then...

नियंत्रण

Dim chk As CheckBox

chk = CType(Me.Controls(chkName), CheckBox)
If chk.Checked Then
    Return chk
End If

एक तो CheckBoxसाथ chkNameनहीं पाया जा सकता है (या एक में मौजूद है GroupBox), तो chkकुछ भी नहीं किया जाएगा और किसी भी संपत्ति एक अपवाद में परिणाम होगा संदर्भित करने के लिए कोशिश कर रहे होंगे।

उपाय

If (chk IsNot Nothing) AndAlso (chk.Checked) Then ...

DataGridView

डीजीवी में समय-समय पर कुछ क्विर्क देखे जाते हैं:

dgvBooks.DataSource = loan.Books
dgvBooks.Columns("ISBN").Visible = True       ' NullReferenceException
dgvBooks.Columns("Title").DefaultCellStyle.Format = "C"
dgvBooks.Columns("Author").DefaultCellStyle.Format = "C"
dgvBooks.Columns("Price").DefaultCellStyle.Format = "C"

यदि dgvBooksहै AutoGenerateColumns = True, तो यह कॉलम बनाएगा, लेकिन यह उन्हें नाम नहीं देता है, इसलिए जब यह उन्हें नाम से संदर्भित करता है तो उपरोक्त कोड विफल हो जाता है।

उपाय

स्तंभों को मैन्युअल रूप से नाम दें, या इंडेक्स द्वारा संदर्भ:

dgvBooks.Columns(0).Visible = True

उदाहरण 2 - NewRow से सावधान रहें

xlWorkSheet = xlWorkBook.Sheets("sheet1")

For i = 0 To myDGV.RowCount - 1
    For j = 0 To myDGV.ColumnCount - 1
        For k As Integer = 1 To myDGV.Columns.Count
            xlWorkSheet.Cells(1, k) = myDGV.Columns(k - 1).HeaderText
            xlWorkSheet.Cells(i + 2, j + 1) = myDGV(j, i).Value.ToString()
        Next
    Next
Next

अपने जब DataGridViewहै AllowUserToAddRowsके रूप में True(डिफ़ॉल्ट), Cellsखाली में / तल पर नई पंक्ति में शामिल होंगे सभी Nothing। सामग्री (उदाहरण के लिए ToString) का उपयोग करने के अधिकांश प्रयासों का परिणाम एक एनआरई होगा।

उपाय

एक For/Eachलूप का उपयोग करें और IsNewRowयह निर्धारित करने के लिए संपत्ति का परीक्षण करें कि क्या यह अंतिम पंक्ति है। यह काम करता AllowUserToAddRowsहै या नहीं यह सच है:

For Each r As DataGridViewRow in myDGV.Rows
    If r.IsNewRow = False Then
         ' ok to use this row

यदि आप For nलूप का उपयोग करते हैं , तो पंक्ति गणना को संशोधित करें या सही Exit Forहोने पर उपयोग करें IsNewRow


My.Settings (StringCollection)

कुछ परिस्थितियों में, उस आइटम का उपयोग करने की कोशिश करना My.Settingsजिससे कोई StringCollectionपरिणाम हो सकता है कि आप इसका उपयोग करने वाले पहली बार NullReference में परिणाम कर सकते हैं। समाधान समान है, लेकिन स्पष्ट नहीं है। विचार करें:

My.Settings.FooBars.Add("ziggy")         ' foobars is a string collection

चूँकि VB आपके लिए सेटिंग्स का प्रबंधन कर रहा है, इसलिए संग्रह को शुरू करने की अपेक्षा करना उचित है। यह होगा, लेकिन केवल अगर आपने पहले संग्रह में एक प्रारंभिक प्रविष्टि (सेटिंग्स संपादक में) जोड़ दी है। चूँकि जब आइटम जोड़ा जाता है तो संग्रह (जाहिरा तौर पर) इनिशियलाइज़ होता है, यह Nothingतब रहता है जब सेटिंग्स एडिटर में कोई आइटम जोड़ने के लिए नहीं होते हैं।

उपाय

प्रपत्र के Loadइवेंट हैंडलर में सेटिंग्स संग्रह को आरम्भ करें, यदि / जब जरूरत हो:

If My.Settings.FooBars Is Nothing Then
    My.Settings.FooBars = New System.Collections.Specialized.StringCollection
End If

आमतौर पर, Settingsसंग्रह को केवल पहली बार शुरू करने की आवश्यकता होगी जब आवेदन चलता है। एक वैकल्पिक उपाय परियोजना में अपने संग्रह के लिए एक प्रारंभिक मूल्य जोड़ना है -> सेटिंग्स | FooBars , प्रोजेक्ट सहेजें, फिर नकली मान निकालें।


प्रमुख बिंदु

आप शायद Newऑपरेटर को भूल गए ।

या

आपके द्वारा ग्रहण की गई किसी वस्तु को आपके कोड के लिए एक इनिशियलाइज़्ड ऑब्जेक्ट वापस करने के लिए निर्दोष प्रदर्शन करेगा।

संकलक चेतावनी (कभी) और उपयोग Option Strict On(हमेशा) को अनदेखा न करें ।


MSDN NullReference अपवाद


226

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

object o = null;
DateTime d = (DateTime)o;

यह NullReferenceExceptionडाली पर फेंक देगा । उपरोक्त नमूने में यह काफी स्पष्ट प्रतीत होता है, लेकिन यह अधिक "लेट-बाइंडिंग" जटिल परिदृश्यों में हो सकता है जहां शून्य ऑब्जेक्ट को कुछ कोड से वापस कर दिया गया है जो आपके पास नहीं है, और कास्ट कुछ स्वचालित सिस्टम द्वारा उत्पन्न उदाहरण के लिए है।

इसका एक उदाहरण कैलेंडर नियंत्रण के साथ यह सरल ASP.NET बाइंडिंग टुकड़ा है:

<asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />

यहां, SelectedDateवास्तव में एक संपत्ति है - DateTimeप्रकार की - Calendarवेब नियंत्रण प्रकार की, और बाइंडिंग पूरी तरह से कुछ अशक्त लौटा सकती है। अंतर्निहित ASP.NET जनरेटर कोड का एक टुकड़ा बनाएगा जो ऊपर दिए गए कास्ट कोड के बराबर होगा। और यह एक जगह उठाना NullReferenceExceptionकाफी मुश्किल होगा, क्योंकि यह ASP.NET जनरेट कोड में निहित है जो ठीक संकलित करता है ...


7
शानदार कैच। बचने का वन-लाइनर तरीका:DateTime x = (DateTime) o as DateTime? ?? defaultValue;
सर्ज Shultz

159

इसका मतलब है कि प्रश्न में चर कुछ भी नहीं में बताया गया है। मैं इसे इस तरह उत्पन्न कर सकता था:

SqlConnection connection = null;
connection.Open();

यह त्रुटि को फेंक देगा क्योंकि जब मैंने चर " connection" घोषित किया है , तो यह कुछ भी इंगित नहीं किया गया है। जब मैं सदस्य को " Open" कॉल करने का प्रयास करता हूं , तो इसके समाधान के लिए कोई संदर्भ नहीं है, और यह त्रुटि को फेंक देगा।

इस त्रुटि से बचने के लिए:

  1. अपने साथ कुछ भी करने की कोशिश करने से पहले हमेशा अपनी वस्तुओं को इनिशियलाइज़ करें।
  2. यदि आप सुनिश्चित नहीं हैं कि ऑब्जेक्ट अशक्त है, तो इसकी जांच करें object == null

JetBrains का Resharper टूल आपके कोड की हर उस जगह की पहचान करेगा, जिसमें एक नल रेफरेंस एरर की संभावना है, जिससे आप एक नल चेक में डाल सकते हैं। यह त्रुटि बग का नंबर एक स्रोत है, IMHO।


3
JetBrains का Resharper टूल आपके कोड की हर उस जगह की पहचान करेगा जिसमें अशक्त संदर्भ त्रुटि की संभावना है। यह गलत है। मेरे पास उस खोज के बिना एक समाधान है, फिर भी कोड कभी-कभी अपवाद के परिणामस्वरूप होता है। मुझे संदेह है कि यह कभी-कभी अवांछनीय है - उनके द्वारा कम से कम - जब मल्टीथ्रेडिंग शामिल है, लेकिन मैं आगे टिप्पणी नहीं कर सकता क्योंकि मैंने अभी तक अपने बग के स्थान की पहचान नहीं की थी।
j riv

लेकिन जब NullReferenceException HttpContext.Current.Responce.Clear () में आता है तो इसे कैसे हल किया जाए। यह उपरोक्त किसी भी समाधान से हल नहीं हो रहा है। क्योंकि HttpContext के अपने ऑब्जेक्ट ऑब्जेक्ट को बनाते समय एक त्रुटि आती है "अधिभार संकल्प विफल हो गया क्योंकि कोई भी सुलभ 'नया' इस तर्क की संख्या को स्वीकार नहीं करता है।
सनी संदीप

157

इसका मतलब है कि आपके कोड ने ऑब्जेक्ट रेफरेंस वैरिएबल का उपयोग किया है जो शून्य पर सेट किया गया था (यानी यह एक वास्तविक ऑब्जेक्ट उदाहरण नहीं था)।

त्रुटि को रोकने के लिए, जिन वस्तुओं को अशक्त किया जा सकता है, उनका उपयोग करने से पहले अशक्त के लिए परीक्षण किया जाना चाहिए।

if (myvar != null)
{
    // Go ahead and use myvar
    myvar.property = ...
}
else
{
    // Whoops! myvar is null and cannot be used without first
    // assigning it to an instance reference
    // Attempting to use myvar here will result in NullReferenceException
}

96

ध्यान रखें कि परिदृश्य की परवाह किए बिना, कारण हमेशा .NET में समान होता है:

आप एक संदर्भ चर का उपयोग करने का प्रयास कर रहे हैं जिसका मान Nothing/ है null। जब मूल्य है Nothing/null संदर्भ चर के लिए , तो इसका मतलब है कि यह वास्तव में ढेर पर मौजूद किसी भी वस्तु के उदाहरण के संदर्भ में नहीं है।

आपने या तो चर को कुछ भी नहीं सौंपा है, चर के लिए दिए गए मान का कोई उदाहरण कभी नहीं बनाया है, या आपने चर को बराबर Nothing/ nullमैन्युअल रूप से सेट किया है , या आपने एक फ़ंक्शन कहा है जो चर को आपके लिए Nothing/ सेट करता है null


87

फेंके जा रहे इस अपवाद का एक उदाहरण है: जब आप किसी चीज़ की जाँच करने की कोशिश कर रहे हैं, तो यह अशक्त है।

उदाहरण के लिए:

string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)

if (testString.Length == 0) // Throws a nullreferenceexception
{
    //Do something
} 

.NET रनटाइम एक NullReferenceException को फेंक देगा, जब आप किसी ऐसी चीज पर कार्रवाई करने का प्रयास करते हैं, जो त्वरित नहीं है अर्थात ऊपर कोड।

एक ArgumentNullException की तुलना में जो आमतौर पर एक रक्षात्मक उपाय के रूप में फेंक दी जाती है यदि कोई विधि यह उम्मीद करती है कि जो उसे पारित किया जा रहा है वह शून्य नहीं है।

अधिक जानकारी C # NullReferenceException और Null Parameter में है


87

अद्यतन C # 8.0, 2019: अशक्त संदर्भ प्रकार

C # 8.0 अशक्त संदर्भ प्रकारों और गैर-अशक्त संदर्भ प्रकारों का परिचय देता है । तो केवल अशक्त संदर्भ प्रकारों को NullReferenceException से बचने के लिए जाँच की जानी चाहिए ।


यदि आपने एक संदर्भ प्रकार को इनिशियलाइज़ नहीं किया है, और आप इसके किसी गुण को सेट या पढ़ना चाहते हैं, तो यह NullReetException को फेंक देगा ।

उदाहरण:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

यदि वेरिएबल शून्य नहीं है, तो आप बस जाँच करके इससे बच सकते हैं:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

यह समझने के लिए कि NullReferenceException को क्यों फेंका गया है, मूल्य प्रकार और [संदर्भ प्रकार] [3] के बीच अंतर को जानना महत्वपूर्ण है ।

इसलिए, यदि आप मान प्रकार के साथ काम कर रहे हैं, तो NullReferenceException नहीं हो सकती है। हालांकि आपको संदर्भ प्रकारों से निपटने के दौरान सतर्क रहने की आवश्यकता है !

केवल संदर्भ प्रकार, जैसा कि नाम से पता चल रहा है, संदर्भ या बिंदु को शाब्दिक रूप से कुछ भी नहीं (या 'अशक्त') रख सकते हैं। जबकि मूल्य प्रकारों में हमेशा एक मूल्य होता है।

संदर्भ प्रकार (इन लोगों की जांच होनी चाहिए):

  • गतिशील
  • वस्तु
  • तार

मूल्य प्रकार (आप केवल इन लोगों को अनदेखा कर सकते हैं):

  • संख्यात्मक प्रकार
  • अभिन्न प्रकार
  • फ्लोटिंग-पॉइंट प्रकार
  • दशमलव
  • bool
  • उपयोगकर्ता परिभाषित संरचनाएं

6
-1: चूँकि प्रश्न "NullReferenceException क्या है", मूल्य प्रकार प्रासंगिक नहीं हैं।
जॉन सॉन्डर्स

21
@ जॉन सॉन्डर्स: मैं असहमत हूं। एक सॉफ्टवेयर डेवलपर के रूप में मूल्य और संदर्भ प्रकारों के बीच अंतर करने में सक्षम होना वास्तव में महत्वपूर्ण है। यदि पूर्णांक अशक्त हैं, तो अन्य लोग जांचना समाप्त कर देंगे।
फेबियन बिगलर

5
सच है, बस इस सवाल के संदर्भ में नहीं।
जॉन सॉन्डर्स

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

5
मुझे लगता है कि आपने कुछ भी नहीं जोड़ा है जो अन्य उत्तरों में नहीं था, क्योंकि प्रश्न एक संदर्भ प्रकार को पूर्व-दबाता है।
जॉन सॉन्डर्स

78

एक और मामला जहां NullReferenceExceptionsहो सकता है वह asऑपरेटर का गलत (गलत) उपयोग है :

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

यहाँ, Bookऔर Carअसंगत प्रकार हैं; एक में Carपरिवर्तित नहीं किया जा सकता है / कास्ट Book। जब यह कलाकार विफल हो जाता है, तो asरिटर्न करता है null। इसके mybookबाद उपयोग करने से एNullReferenceException

सामान्य तौर पर, आपको एक कास्ट का उपयोग करना चाहिए या as, निम्नानुसार करना चाहिए :

यदि आप टाइप रूपांतरण की अपेक्षा कर रहे हैं कि आप हमेशा सफल रहें (यानी आप जानते हैं कि समय से पहले वस्तु क्या होनी चाहिए), तो आपको एक भुगतान करना चाहिए:

ComicBook cb = (ComicBook)specificBook;

यदि आप प्रकार के अनिश्चित हैं, लेकिन आप इसे एक विशिष्ट प्रकार के रूप में उपयोग करने का प्रयास करना चाहते हैं , तो उपयोग करें as:

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}

2
वैरिएबल को अनबॉक्स करते समय यह बहुत कुछ हो सकता है । मुझे लगता है कि इवेंट हैंडलर में अक्सर ऐसा होता है क्योंकि मैंने यूआई तत्व के प्रकार को बदल दिया था, लेकिन कोड-पीछे अपडेट करना भूल गया।
ब्रेंडन

65

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

उदाहरण:

string value = null;
if (value.Length == 0) // <-- Causes exception
{
    Console.WriteLine(value); // <-- Never reached
}

अपवाद त्रुटि है:

अनियंत्रित अपवाद:

System.NullReferenceException: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति के लिए सेट नहीं है। कार्यक्रम में। मेन ()


1
कितना गहरा है! मैंने कभी भी 'null' को रेफरेंस वैल्यू नहीं माना। तो यह है कि कैसे सी # सार एक "NullPointer" हुह? B / c जैसा कि मुझे C ++ में याद आता है, एक एनपीई एक अनइंस्टॉलिज्ड पॉइंटर (यानी, रेफरी प्रकार c # में) के कारण हो सकता है, जिसका डिफ़ॉल्ट मान एक पता है जो उस प्रक्रिया को आवंटित नहीं होता है (कई मामलों में यह 0 होगा,) विशेष रूप से C ++ के बाद के संस्करणों में, जिन्होंने ऑटो-इनिशियलाइज़ेशन किया था, जो ओएस से संबंधित है - इसके साथ एफ और डाई बीओटेक (या सिगकिल को पकड़ें ओएस आपके साथ की प्रक्रिया पर हमला करता है)।
समिस जूल

64

हालांकि इस तरह के अपवाद से बचने / ठीक करने के लिए एक NullReferenceException और दृष्टिकोण का क्या कारण होता है, अन्य उत्तरों में संबोधित किया गया है, जो कई प्रोग्रामर अभी तक नहीं सीख पाए हैं कि विकास के दौरान ऐसे अपवादों को कैसे स्वतंत्र रूप से डिबग किया जाए

विजुअल स्टूडियो में यह आमतौर पर विज़ुअल स्टूडियो डीबगर के लिए आसान धन्यवाद है ।


पहले, सुनिश्चित करें कि सही त्रुटि पकड़ी जा रही है - देखें कि मैं VS2010 में 'System.NullReferenceException' पर टूटने की अनुमति कैसे दूं? नोट 1

तो फिर या तो प्रारंभ डिबगिंग (F5) के साथ या संलग्न [वी.एस. डीबगर] चल रही प्रक्रिया के लिए । मौके पर यह उपयोग करने के लिए उपयोगी हो सकता है Debugger.Break, जो डिबगर को लॉन्च करने के लिए संकेत देगा।

अब, जब NullReferenceException को फेंक दिया जाता है (या अनहेल्ड किया जाता है) डीबगर बंद हो जाएगा (उस नियम को याद रखें? ऊपर लाइन पर?) जिस पर अपवाद हुआ। कभी-कभी त्रुटि को स्पॉट करना आसान होगा।

उदाहरण के लिए, निम्न पंक्ति में केवल कोड है कि कर सकते हैं अपवाद के कारण अगर है myStringमूल्यांकन करता अशक्त करने के लिए। यह वॉच विंडो को देखकर या तत्काल विंडो में चल रहे अभिव्यक्तियों को सत्यापित किया जा सकता है ।

var x = myString.Trim();

अधिक उन्नत मामलों में, जैसे कि निम्नलिखित, आपको उपरोक्त तकनीकों में से एक (वॉच या तत्काल विंडोज) का उपयोग करने की आवश्यकता होगी, यह निर्धारित करने के लिए कि क्या str1अशक्त था या यदि अशक्त था, तो निरीक्षण करने के लिए str2

var x = str1.Trim() + str2.Trim();

एक बार जहां अपवाद को फेंक दिया गया है, वहां आमतौर पर यह पता लगाने के लिए कि तुच्छ मान कहाँ था, यह पता लगाने के लिए तुच्छ है कि यह गलत तरीके से पेश किया गया था -

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


1 यदि थ्रो पर ब्रेक बहुत आक्रामक है और डीबगर .NET या 3-पार्टी लाइब्रेरी में एक एनपीई पर रुक जाता है, तो पकड़े गए अपवादों को सीमित करने के लिए यूजर-अनहेल्ड पर ब्रेक का उपयोग किया जा सकता है। इसके अतिरिक्त, VS2012 जस्ट माई कोड का परिचय देता है जिसे मैं सक्षम करने की सलाह देता हूं।

यदि आप जस्ट माई कोड सक्षम के साथ डिबगिंग कर रहे हैं, तो व्यवहार थोड़ा अलग है। जस्ट माई कोड सक्षम होने के साथ, डिबगर पहले-अवसर की सामान्य भाषा रनटाइम (CLR) अपवादों को अनदेखा करता है, जो मेरे कोड के बाहर फेंक दिए जाते हैं और मेरे कोड से नहीं गुजरते हैं


59

साइमन मॉरियर ने यह उदाहरण दिया :

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

जहां एक unboxing रूपांतरण (डाली) से object (या वर्गों में से एक से System.ValueTypeया System.Enum, या एक इंटरफ़ेस प्रकार से) के लिए एक मान प्रकार (के अलावा अन्य Nullable<>) अपने आप में देता हैNullReferenceException

दूसरी दिशा में, एक बॉक्सिंग रूपांतरण से एक Nullable<>जो है HasValueके बराबर false करने के लिए एक संदर्भ के प्रकार, एक दे सकते हैं nullसंदर्भ जो फिर बाद में एक को जन्म दे सकता NullReferenceException। क्लासिक उदाहरण है:

DateTime? d = null;
var s = d.ToString();  // OK, no exception (no boxing), returns ""
var t = d.GetType();   // Bang! d is boxed, NullReferenceException

कभी-कभी बॉक्सिंग दूसरे तरीके से होती है। इस गैर-जेनेरिक एक्सटेंशन विधि के साथ उदाहरण के लिए:

public static void MyExtension(this object x)
{
  x.ToString();
}

निम्नलिखित कोड समस्याग्रस्त होगा:

DateTime? d = null;
d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.

बॉक्सिंग के Nullable<>उदाहरणों के दौरान रनटाइम का उपयोग करने वाले विशेष नियमों के कारण ये मामले उत्पन्न होते हैं ।


42

एक ऐसा मामला जोड़ना जब इकाई ढांचे में प्रयुक्त इकाई का वर्ग नाम वेब प्रपत्र कोड-पीछे फ़ाइल के वर्ग नाम के समान हो।

मान लीजिए कि आपके पास एक वेब फ़ॉर्म Contact.aspx है जिसका कोडबेहाइंड संपर्क है और आपके पास एक इकाई का नाम संपर्क है।

जब आप संदर्भ कहते हैं तब निम्नलिखित कोड एक NullReferenceException फेंक देगा। ShaveChanges ()

Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line

संपूर्णता के लिए DataContext वर्ग

public class DataContext : DbContext 
{
    public DbSet<Contact> Contacts {get; set;}
}

और संपर्क इकाई वर्ग। कभी-कभी इकाई वर्ग आंशिक वर्ग होते हैं ताकि आप उन्हें अन्य फ़ाइलों में भी विस्तारित कर सकें।

public partial class Contact 
{
    public string Name {get; set;}
}

त्रुटि तब होती है जब दोनों निकाय और कोडबिहिन वर्ग समान नामस्थान में होते हैं। इसे ठीक करने के लिए, संपर्क वर्ग के लिए संस्था वर्ग या Codebehind वर्ग का नाम बदलें ।aspx।

कारण मैं अभी भी कारण के बारे में निश्चित नहीं हूं। लेकिन जब भी कोई इकाई वर्ग System.Web.UI का विस्तार करेगा। इस त्रुटि के कारण होता है।

चर्चा के लिए DbContext.saveChanges () में NullReferenceException पर एक नज़र डालें


41

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

कुछ हद तक उदाहरण के लिए कस्टम ऑथोराइज़ेशन एट्रिब्यूट का परीक्षण करते समय " NullReferenceException " को देखें ।


40

इसका उत्तर देने के लिए मेरे पास एक अलग दृष्टिकोण है। इस तरह के जवाब "मैं इससे बचने के लिए और क्या कर सकता हूं? "

विभिन्न परतों में काम करते समय , उदाहरण के लिए एक एमवीसी एप्लिकेशन में, एक नियंत्रक को व्यावसायिक कार्यों को कॉल करने के लिए सेवाओं की आवश्यकता होती है। ऐसे परिदृश्यों में NullReferenceException से बचने के लिए सेवाओं को प्रारंभ करने के लिए निर्भरता इंजेक्शन कंटेनर का उपयोग किया जा सकता है । इसका मतलब है कि आपको अशक्त के लिए जाँच करने के बारे में चिंता करने की आवश्यकता नहीं है और बस नियंत्रक से सेवाओं को कॉल करें क्योंकि वे हमेशा उपलब्ध हैं (और आरंभिक) या तो एक सिंगलटन या एक प्रोटोटाइप के रूप में।

public class MyController
{
    private ServiceA serviceA;
    private ServiceB serviceB;

    public MyController(ServiceA serviceA, ServiceB serviceB)
    {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
    }

    public void MyMethod()
    {
        // We don't need to check null because the dependency injection container 
        // injects it, provided you took care of bootstrapping it.
        var someObject = serviceA.DoThis();
    }
}

6
-1: यह केवल एक ही परिदृश्य को संभालता है - जो कि एकतरफा निर्भरता है। यह NullReferenceException के लिए एक अल्पसंख्यक परिदृश्य है। अधिकांश मामले सरल गलतफहमी हैं कि ऑब्जेक्ट कैसे काम करते हैं। अगली सबसे अधिक बार अन्य स्थितियां होती हैं, जहां डेवलपर ने मान लिया था कि ऑब्जेक्ट को स्वचालित रूप से प्रारंभ किया जाएगा।
जॉन सॉन्डर्स

NullReferenceException से बचने के लिए आमतौर पर निर्भरता इंजेक्शन का उपयोग नहीं किया जाता है। मुझे विश्वास नहीं होता कि आपको यहां एक सामान्य परिदृश्य मिला है। किसी भी स्थिति में, यदि आप stackoverflow.com/a/15232518/76337 की शैली में अपने उत्तर को अधिक संपादित करते हैं , तो मैं डाउनवोट को हटा दूंगा।
जॉन सॉन्डर्स

38

"मुझे इसके बारे में क्या करना चाहिए" की बात पर , कई जवाब हो सकते हैं।

विकसित करते समय ऐसी त्रुटि स्थितियों को रोकने का एक अधिक "औपचारिक" तरीका आपके कोड में अनुबंध द्वारा डिजाइन लागू कर रहा है । इसका मतलब है आप सेट वर्ग की जरूरत अपरिवर्तनशीलताओं , और / या यहां तक कि समारोह / विधि पूर्व शर्त और postconditions आपके सिस्टम पर है, जबकि विकासशील।

संक्षेप में, वर्ग के आक्रमणकारी यह सुनिश्चित करते हैं कि आपकी कक्षा में कुछ अड़चनें होंगी जो सामान्य उपयोग में उल्लंघन नहीं करेंगी (और इसलिए, वर्ग असंगत स्थिति में नहीं मिलेगा)। Preconditions का मतलब है कि किसी फ़ंक्शन / मेथड के इनपुट के रूप में दिए गए डेटा को कुछ बाधाओं का पालन करना चाहिए और उनका उल्लंघन कभी नहीं करना चाहिए, और पोस्टकंडिशन का अर्थ है कि फ़ंक्शन / मेथोड आउटपुट को कभी भी उल्लंघन किए बिना सेट की कमी का पालन करना चाहिए। बग-मुक्त कार्यक्रम के निष्पादन के दौरान अनुबंध की शर्तों का कभी भी उल्लंघन नहीं किया जाना चाहिए , इसलिए अनुबंध द्वारा डिजाइन को डिबग मोड में अभ्यास में जांचा जाता है, जबकि रिलीज में अक्षम होने के दौरान , विकसित सिस्टम प्रदर्शन को अधिकतम करने के लिए।

इस तरह, आप उन NullReferenceExceptionमामलों से बच सकते हैं जो निर्धारित बाधाओं के उल्लंघन के परिणाम हैं। उदाहरण के लिए, यदि आप Xकिसी क्लास में ऑब्जेक्ट प्रॉपर्टी का उपयोग करते हैं और बाद में इसके किसी एक तरीके को लागू करने की कोशिश करते हैं और Xइसका एक शून्य मान है, तो यह इस प्रकार होगा NullReferenceException:

public X { get; set; }

public void InvokeX()
{
    X.DoSomething(); // if X value is null, you will get a NullReferenceException
}

लेकिन अगर आपने "प्रॉपर्टी एक्स को कभी शून्य मान नहीं होना चाहिए" विधि पूर्व शर्त के रूप में, तो आप पहले वर्णित परिदृश्य को रोक सकते हैं:

//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant () 
{
    Contract.Invariant ( X != null );
    //...
}

इस कारण से, .NET कॉन्ट्रैक्ट्स प्रोजेक्ट .NET अनुप्रयोगों के लिए मौजूद है।

वैकल्पिक रूप से, अनुबंध द्वारा डिजाइन अभिकथन का उपयोग करके लागू किया जा सकता है ।

अद्यतन: यह उल्लेखनीय है कि यह शब्द बर्ट्रेंड मेयर ने एफिल प्रोग्रामिंग भाषा के अपने डिजाइन के संबंध में बनाया था ।


2
मैंने इसे जोड़ने के लिए सोचा क्योंकि किसी ने भी इसका उल्लेख नहीं किया है, और जहां तक ​​यह एक दृष्टिकोण के रूप में मौजूद है, मेरा उद्देश्य विषय को समृद्ध करना था।
निक लुलाउदकिस

2
विषय को समृद्ध करने के लिए धन्यवाद। मैंने आपके अलावा अपनी राय दी है। अब दूसरे भी ऐसा कर सकते हैं।
जॉन सॉन्डर्स

2
मैंने सोचा था कि यह दिए गए विषय के अतिरिक्त सार्थक था कि यह एक उच्च देखा गया धागा है। मैंने पहले कोड कॉन्ट्रैक्ट के बारे में सुना है और उनका उपयोग करने पर विचार करने के लिए यह एक अच्छा अनुस्मारक था।
वोट कॉफ़ी

36

NullReferenceExceptionतब फेंका जाता है जब हम एक अशक्त वस्तु के गुणों का उपयोग करने की कोशिश कर रहे हैं या जब एक स्ट्रिंग मान रिक्त हो जाता है और हम स्ट्रिंग विधियों तक पहुंचने का प्रयास कर रहे हैं।

उदाहरण के लिए:

  1. जब एक खाली स्ट्रिंग की एक स्ट्रिंग विधि एक्सेस की जाती है:

    string str = string.Empty;
    str.ToLower(); // throw null reference exception
  2. जब किसी अशक्त वस्तु की संपत्ति एक्सेस की जाती है:

    Public Class Person {
        public string Name { get; set; }
    }
    Person objPerson;
    objPerson.Name  /// throw Null refernce Exception 

2
यह गलत है। String.Empty.ToLower()एक अशक्त संदर्भ अपवाद नहीं फेंकेंगे। यह एक वास्तविक स्ट्रिंग का प्रतिनिधित्व करता है, भले ही एक खाली (यानी "")। चूंकि इस ToLower()पर कॉल करने के लिए एक ऑब्जेक्ट है , इसलिए यह एक शून्य संदर्भ अपवाद को फेंकने के लिए कोई मतलब नहीं होगा।
कर्जरतन

31

TL; DR: केHtml.Partial बजाय का उपयोग करने का प्रयास करेंRenderpage


Object reference not set to an instance of an objectजब मैं इसे एक मॉडल भेजकर एक दृश्य के भीतर एक दृश्य को प्रस्तुत करने की कोशिश कर रहा था , तो इस तरह से:

@{
    MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null

डिबगिंग ने दिखाया कि मॉडल MyOtherView के अंदर अशक्त था। जब तक मैंने इसे नहीं बदला:

@{
    MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);

और इसने काम किया।

इसके अलावा, जिस कारण से मुझे Html.Partialशुरुआत नहीं करनी पड़ी, क्योंकि विजुअल स्टूडियो कभी - कभी एरर दिखने वाली स्क्वीजीली लाइनों को फेंक देता है, Html.Partialअगर यह एक अलग तरीके से निर्मित foreachलूप के अंदर है , भले ही यह वास्तव में एक त्रुटि न हो:

@inherits System.Web.Mvc.WebViewPage
@{
    ViewBag.Title = "Entity Index";
    List<MyEntity> MyEntities = new List<MyEntity>();
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
}
<div>
    @{
        foreach(var M in MyEntities)
        {
            // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
            @Html.Partial("MyOtherView.cshtml");
        }
    }
</div>

लेकिन मैं इस "त्रुटि" के साथ कोई समस्या नहीं के साथ आवेदन को चलाने में सक्षम था। मैं foreachइस तरह दिखने के लिए लूप की संरचना को बदलकर त्रुटि से छुटकारा पाने में सक्षम था :

@foreach(var M in MyEntities){
    ...
}

हालाँकि मुझे ऐसा लग रहा है क्योंकि विजुअल स्टूडियो एम्परसेंड और ब्रैकेट का गलत इस्तेमाल कर रहा था।


आप चाहते थे Html.Partial, नहीं@Html.Partial
जॉन सैन्डर्स

इसके अलावा, कृपया बताएं कि किस लाइन ने अपवाद को फेंक दिया, और क्यों।
जॉन सॉन्डर्स

त्रुटि MyOtherView.cshtml में हुई, जिसे मैंने यहां शामिल नहीं किया, क्योंकि मॉडल को ठीक से इसमें नहीं भेजा जा रहा था (यह था Null), इसलिए मुझे पता था कि त्रुटि यह थी कि मैं मॉडल को अंदर कैसे भेज रहा था।
ट्रैविस हेटर जूल

22

आप इसके बारे में क्या कर सकते हैं?

यहाँ बहुत सारे अच्छे उत्तर हैं जो बताते हैं कि एक अशक्त संदर्भ क्या है और इसे कैसे डीबग करना है। लेकिन इस मुद्दे को रोकने के लिए या कम से कम इसे पकड़ने में आसान बनाने के तरीके पर बहुत कम है।

तर्कों की जाँच करें

उदाहरण के लिए, विधियाँ अलग-अलग तर्कों की जाँच कर सकती हैं कि क्या वे अशक्त हैं और उन्हें फेंक देते हैं ArgumentNullException, एक अपवाद स्पष्ट रूप से इस सटीक उद्देश्य के लिए बनाया गया है।

ArgumentNullExceptionयहां तक ​​कि कंस्ट्रक्टर भी पैरामीटर का नाम लेता है और तर्क के रूप में एक संदेश देता है ताकि आप डेवलपर को बता सकें कि समस्या क्या है।

public void DoSomething(MyObject obj) {
    if(obj == null) 
    {
        throw new ArgumentNullException("obj", "Need a reference to obj.");
    }
}

उपकरण का उपयोग करें

कई पुस्तकालय भी हैं जो मदद कर सकते हैं। उदाहरण के लिए "रिचार्पर" आपको कोड लिखते समय चेतावनी दे सकता है, खासकर यदि आप उनकी विशेषता का उपयोग करते हैं: NotNullAttribute

वहाँ "Microsoft कोड कॉन्ट्रैक्ट्स" होता है जहाँ आप सिंटैक्स का उपयोग करते हैं, Contract.Requires(obj != null)जो आपको रनटाइम देता है और जाँच करता है: कोड कॉन्ट्रैक्ट्स का परिचय

वहाँ भी है "PostSharp" जो आपको इस तरह की विशेषताओं का उपयोग करने की अनुमति देगा:

public void DoSometing([NotNull] obj)

ऐसा करने से और आपकी बिल्ड प्रक्रिया का PostSharp भाग बनाने के objलिए रनटाइम पर नल की जाँच की जाएगी। देखें: PostSharp अशक्त जाँच

सादा कोड समाधान

या आप हमेशा पुराने पुराने कोड का उपयोग करके अपने स्वयं के दृष्टिकोण को कोड कर सकते हैं। उदाहरण के लिए यहां एक संरचना है जिसे आप अशक्त संदर्भों को पकड़ने के लिए उपयोग कर सकते हैं। इसे उसी अवधारणा के बाद बनाया गया है Nullable<T>:

[System.Diagnostics.DebuggerNonUserCode]
public struct NotNull<T> where T: class
{
    private T _value;

    public T Value
    {
        get
        {
            if (_value == null)
            {
                throw new Exception("null value not allowed");
            }

            return _value;
        }
        set
        {
            if (value == null)
            {
                throw new Exception("null value not allowed.");
            }

            _value = value;
        }
    }

    public static implicit operator T(NotNull<T> notNullValue)
    {
        return notNullValue.Value;
    }

    public static implicit operator NotNull<T>(T value)
    {
        return new NotNull<T> { Value = value };
    }
}

आप बिल्कुल उसी तरह का उपयोग करेंगे जैसे आप उपयोग करेंगे Nullable<T>, बिल्कुल विपरीत को पूरा करने के लक्ष्य के अलावा - अनुमति नहीं देने के लिए null। यहाँ कुछ उदाहरण हैं:

NotNull<Person> person = null; // throws exception
NotNull<Person> person = new Person(); // OK
NotNull<Person> person = GetPerson(); // throws exception if GetPerson() returns null

NotNull<T>से अनुमानित रूप से है और Tइसलिए आप इसका उपयोग कर सकते हैं बस के बारे में कहीं भी आप की जरूरत है। उदाहरण के लिए, आप किसी Personऑब्जेक्ट को एक विधि में पास कर सकते हैं जो एक NotNull<Person>:

Person person = new Person { Name = "John" };
WriteName(person);

public static void WriteName(NotNull<Person> person)
{
    Console.WriteLine(person.Value.Name);
}

जैसा कि आप अशक्त के साथ ऊपर देख सकते हैं कि आप Valueसंपत्ति के माध्यम से अंतर्निहित मूल्य तक पहुंचेंगे । वैकल्पिक रूप से, आप एक स्पष्ट या निहित कलाकारों का उपयोग कर सकते हैं, आप नीचे दिए गए रिटर्न मान के साथ एक उदाहरण देख सकते हैं:

Person person = GetPerson();

public static NotNull<Person> GetPerson()
{
    return new Person { Name = "John" };
}

या आप इसका उपयोग तब भी कर सकते हैं जब विधि सिर्फ एक कास्ट करके T(इस मामले में Person) वापस आती है । उदाहरण के लिए, निम्न कोड ऊपर दिए गए कोड की तरह होगा:

Person person = (NotNull<Person>)GetPerson();

public static Person GetPerson()
{
    return new Person { Name = "John" };
}

एक्सटेंशन के साथ मिलाएं

NotNull<T>एक विस्तार विधि के साथ गठबंधन करें और आप और भी अधिक स्थितियों को कवर कर सकते हैं। विस्तार विधि क्या दिख सकती है, इसका एक उदाहरण इस प्रकार है:

[System.Diagnostics.DebuggerNonUserCode]
public static class NotNullExtension
{
    public static T NotNull<T>(this T @this) where T: class
    {
        if (@this == null)
        {
            throw new Exception("null value not allowed");
        }

        return @this;
    }
}

और इसका एक उदाहरण है कि इसका उपयोग कैसे किया जा सकता है:

var person = GetPerson().NotNull();

GitHub

आपके संदर्भ के लिए मैंने ऊपर GitHub पर कोड उपलब्ध कराया, आप इसे यहाँ पा सकते हैं:

https://github.com/luisperezphd/NotNull

संबंधित भाषा फ़ीचर

सी # 6.0 ने "नल-सशर्त ऑपरेटर" को पेश किया जो इसे थोड़ा मदद करता है। इस सुविधा के साथ, आप नेस्टेड ऑब्जेक्ट्स को संदर्भित कर सकते हैं और यदि उनमें से कोई एक nullपूरी अभिव्यक्ति रिटर्न है null

यह कुछ मामलों में आपको किए जाने वाले शून्य चेक की संख्या को कम कर देता है। वाक्य-विन्यास को प्रत्येक बिंदु से पहले प्रश्न चिह्न लगाना है। उदाहरण के लिए निम्न कोड लें:

var address = country?.State?.County?.City;

कल्पना कीजिए कि countryएक प्रकार की एक वस्तु Countryहै जिसमें एक संपत्ति है जिसे बुलाया जाता है Stateऔर इसी तरह। तो country, State, County, या Cityहै nullतो address will beअशक्त . Therefore you only have to check whetherपताis null`।

यह एक बड़ी विशेषता है, लेकिन यह आपको कम जानकारी देता है। यह स्पष्ट नहीं करता है कि 4 में से कौन सा शून्य है।

बिल्ट-इन Nullable की तरह?

C # के लिए एक अच्छा शॉर्टहैंड है Nullable<T>, आप इस प्रकार के बाद प्रश्न चिह्न लगाकर कुछ अशक्त कर सकते हैं int?

यह अच्छा होगा यदि C # में NotNull<T>ऊपर की संरचना जैसी कोई चीज़ होती और उसके पास एक समान शॉर्टहैंड होता, शायद विस्मयादिबोधक बिंदु (!) ताकि आप कुछ ऐसा लिख ​​सकें:public void WriteName(Person! person) :।


2
कभी नहीं NullReferenceException
John Saunders

@ जॉनसंडर्स की हिम्मत है कि मैं क्यों पूछूं? (गंभीरता से हालांकि क्यों?)
लुइस पेरेज़

2
NullReferenceException CLR द्वारा फेंके जाने का मतलब है। इसका मतलब है कि एक अशक्त का संदर्भ हुआ है। इसका मतलब यह नहीं है कि एक अशक्त का संदर्भ हो सकता है सिवाय इसके कि आपने पहले चतुराई से जांच की।
जॉन सॉन्डर्स

मैं आपकी बात देखता हूं कि यह कैसे भ्रमित होगा। मैंने इसे इस उदाहरण के लिए एक नियमित अपवाद और GitHub में एक कस्टम अपवाद के लिए अद्यतन किया है।
लुईस पेरेस

इस तरह के मूल प्रश्न के लिए बढ़िया जवाब। यह इतना बुरा नहीं है जब यह आपका कोड है जो विफल हो रहा है। यह भयानक है जब आप किसी वाणिज्यिक थर्ड पार्टी लाइब्रेरी के अंदर गहरे से आ रहे हैं, जिस पर आप भरोसा कर रहे हैं, और ग्राहक समर्थन इस बात पर जोर देता रहता है कि उसे आपका कोड होना चाहिए जो समस्या पैदा कर रहा है। और आपका पूरा यकीन नहीं है कि यह नहीं है और पूरी परियोजना रुक रही है .. मुझे वास्तव में लगता है कि यह मेरे मकबरे के लिए एक उपयुक्त एपिटैफ़ बना सकता है: "ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं है।"
डारेल ली

10

दिलचस्प बात यह है कि इस पृष्ठ पर कोई भी उत्तर दो किनारे के मामलों का उल्लेख नहीं करता है, आशा है कि अगर मैं उन्हें जोड़ दूं तो कोई भी बुरा नहीं मानता:

एज केस # 1: एक शब्दकोश के लिए समवर्ती पहुँच

.NET में जेनेरिक शब्दकोश थ्रेड-सुरक्षित नहीं हैं और वे कभी - कभीNullReference या (अधिक लगातार) ए भी फेंक सकते हैंKeyNotFoundException जब आप दो समवर्ती धागों से एक कुंजी को एक्सेस करने का प्रयास करते हैं तो । इस मामले में अपवाद काफी भ्रामक है।

एज केस # 2: असुरक्षित कोड

यदि कोड NullReferenceExceptionद्वारा फेंक दिया गया है unsafe, तो आप अपने पॉइंटर चर को देख सकते हैं, और उन्हें जांच सकते हैंIntPtr.Zero या कुछ के । जो एक ही बात है ("शून्य सूचक अपवाद"), लेकिन असुरक्षित कोड में, चर अक्सर मूल्य-प्रकार / सरणियों, आदि के लिए डाली जाती हैं, और आप दीवार के खिलाफ अपना सिर धमाका करते हैं, यह सोचकर कि मूल्य-प्रकार इसे कैसे फेंक सकते हैं अपवाद।

(असुरक्षित कोड का उपयोग न करने का एक अन्य कारण जब तक आपको इसकी आवश्यकता नहीं है, वैसे)


5
आपका शब्दकोश उदाहरण एक किनारे का मामला नहीं है। यदि ऑब्जेक्ट थ्रेड सुरक्षित नहीं है, तो इसे कई थ्रेड्स से उपयोग करना यादृच्छिक परिणाम उत्पन्न करता है। आपका असुरक्षित कोड उदाहरण nullकिस तरह से अलग है ?
जॉन सॉन्डर्स

10

Null-सशर्त ऑपरेटर्स को c # 6 का उपयोग करके आप एक साफ तरीके से NullReferenceException को ठीक कर सकते हैं और अशक्त जांच को संभालने के लिए कम कोड लिख सकते हैं।

इसका उपयोग एक सदस्य पहुंच (?) या इंडेक्स (? [) ऑपरेशन करने से पहले अशक्त के लिए परीक्षण करने के लिए किया जाता है।

उदाहरण

  var name = p?.Spouse?.FirstName;

के बराबर है:

    if (p != null)
    {
        if (p.Spouse != null)
        {
            name = p.Spouse.FirstName;
        }
    }

नतीजा यह है कि नाम शून्य होगा जब p शून्य है या जब p.Spouse शून्य है।

अन्यथा, चर नाम को p.Spouse.FirstName का मान असाइन किया जाएगा।

अधिक जानकारी के लिए: अशक्त-संचालक


9

त्रुटि लाइन "ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण के लिए सेट नहीं है।" बताता है कि आपने ऑब्जेक्ट ऑब्जेक्ट को इंस्टेंस ऑब्जेक्ट को नहीं सौंपा है और फिर भी आप उस ऑब्जेक्ट की उचितियों / विधियों तक पहुंच बना रहे हैं।

उदाहरण के लिए: मान लें कि आपके पास myClass नामक एक वर्ग है और इसमें एक संपत्ति Prop1 है।

public Class myClass
{
   public int prop1 {get;set;}
}

अब आप इस प्रॉप 1 को नीचे की तरह किसी अन्य वर्ग में पहुँचा रहे हैं:

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref.prop1 = 1;  //This line throws error
     }
}

उपरोक्त लाइन त्रुटि को फेंकती है क्योंकि वर्ग myClass का संदर्भ घोषित किया गया है, लेकिन तात्कालिक या वस्तु का एक उदाहरण उस वर्ग के संदर्भ के लिए निर्दिष्ट नहीं किया गया है।

इसे ठीक करने के लिए आपको तुरंत (उस वर्ग के संदर्भ में ऑब्जेक्ट असाइन करना होगा)।

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref = new myClass();
        ref.prop1 = 1;  
     }
}

4

NullReferenceException या ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के इंस्टेंस पर सेट नहीं होता है, जब आप जिस क्लास का उपयोग करने का प्रयास कर रहे हैं, उस ऑब्जेक्ट का इंस्टेंटिएटेड नहीं है। उदाहरण के लिए:

मान लें कि आपके पास छात्र नाम का एक वर्ग है।

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

अब, एक और कक्षा पर विचार करें जहाँ आप छात्र का पूरा नाम पुनः प्राप्त करने का प्रयास कर रहे हैं।

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

जैसा कि ऊपर दिए गए कोड में देखा गया है, छात्र का कथन - केवल छात्र का चर घोषित करता है, ध्यान दें कि छात्र वर्ग इस बिंदु पर त्वरित नहीं है। इसलिए, जब कथन s.GetFullName () निष्पादित हो जाता है, तो यह NullReferenceException को फेंक देगा।


3

ठीक है, सरल शब्दों में:

आप उस ऑब्जेक्ट तक पहुँचने का प्रयास कर रहे हैं जो अभी बना नहीं है या वर्तमान में मेमोरी में नहीं है।

तो इससे कैसे निपटा जाए:

  1. डीबग करें और डीबगर को विराम दें ... यह सीधे आपको उस चर पर ले जाएगा जो टूट गया है ... अब आपका कार्य बस इसे ठीक करना है .. नए कीवर्ड का उपयोग उचित स्थान पर करना।

  2. यदि यह कुछ डेटाबेस कमांड्स पर होता है क्योंकि ऑब्जेक्ट मौजूद नहीं है, तो आपको बस इतना करना है कि एक अशक्त जांच करें और इसे संभाल लें:

    if (i == null) {
        // Handle this
    }
  3. सबसे कठिन .. यदि GC ने पहले ही ऑब्जेक्ट एकत्र कर लिया है ... यह आमतौर पर तब होता है जब आप स्ट्रिंग्स का उपयोग करके ऑब्जेक्ट खोजने का प्रयास कर रहे हैं ... अर्थात, इसे ऑब्जेक्ट के नाम से ढूंढना है तो ऐसा हो सकता है कि GC पहले से ही हो सकता है इसे साफ कर दिया ... यह खोजने के लिए कठिन है और काफी समस्या बन जाएगा ... इससे निपटने का एक बेहतर तरीका यह है कि विकास प्रक्रिया के दौरान जहां भी आवश्यक हो, अशक्त जांच करें। इससे आपका काफी समय बचेगा।

नाम से खोजने से मेरा मतलब है कि कुछ ढांचे आपको स्ट्रिंग का उपयोग करके FIndObjects की अनुमति देते हैं और कोड इस तरह दिख सकता है: FindObject ("ObjectName");


3
यदि आपके पास किसी ऑब्जेक्ट का संदर्भ है, तो जीसी कभी भी इसे साफ नहीं करता है
जॉन सॉन्डर्स

2
यदि आप FindObject ("ऑब्जेक्ट का नाम") जैसी चीज़ों का उपयोग करते हैं, तो कोई रास्ता नहीं है GC को हाथ से पहले पता चल जाएगा कि आप उस ऑब्जेक्ट को रेफ़रेन्स करने जा रहे हैं .. यही वह है जो विस्फोट करने की कोशिश कर रहा था .. ये रनटाइम पर होते हैं
आकाश गंगा

2
कुछ ऐसे फ्रेमवर्क हैं जो C # में यह कार्यक्षमता प्रदान करते हैं जैसे कि एकता। प्रश्न में BCl से संबंधित कुछ भी नहीं है। समालोचना करने से पहले इंटरनेट पर सर्च करें कि उनके जैसे एक टन फ़ंक्शन हैं और उर तरह की जानकारी के लिए मैं इसे दैनिक रूप से उपयोग करता हूं। अब कृपया मुझे बताएं कि उत्तर कैसे भी नहीं बनाता है।
आकाश गुत्थ

2
docs.unity3d.com/ScriptReference/… लिंक की जाँच करें और अपने आप को urr mr.expert: p
Akut Gutha

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

1

मूल रूप से NullReferenceExeption को ठीक करने का सबसे आसान तरीका दो तरीके हैं। यदि आपके पास उदाहरण के लिए एक GameObject जुड़ा हुआ है और लिपि में rb (rigidbody) नाम का एक चर है, तो यह चर आपके खेल को शुरू करते समय अशक्त हो जाएगा।
यही कारण है कि आपको NullReferenceExeption मिलता है क्योंकि कंप्यूटर में उस चर में संग्रहीत डेटा नहीं होता है।

मैं एक उदाहरण के रूप में एक RigidBody चर का उपयोग करूँगा।
हम वास्तव में आसानी से वास्तव में कुछ तरीकों से डेटा जोड़ सकते हैं:

  1. AddComponent> Physics> Rigidbody के साथ अपनी ऑब्जेक्ट में एक RigidBody जोड़ें
    फिर अपनी स्क्रिप्ट में जाएं और rb = GetComponent<Rigidbody>();
    कोड की यह पंक्ति आपके Start()या Awake()फ़ंक्शंस के तहत सबसे अच्छा काम करती है।
  2. आप एक घटक को प्रोग्रामेटिक रूप से जोड़ सकते हैं और एक ही समय में कोड को एक लाइन की कोड के साथ असाइन कर सकते हैं: rb = AddComponent<RigidBody>();

आगे के नोट्स: यदि आप एकता को अपनी वस्तु में जोड़ना चाहते हैं और आप एक को जोड़ना भूल गए हैं, तो आप [RequireComponent(typeof(RigidBody))]अपनी कक्षा की घोषणा (आपके सभी विवरणों के नीचे का स्थान) से ऊपर टाइप कर सकते हैं ।
आनंद लें और खेल बनाने का मज़ा लें!


-1

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

उदाहरण के लिए:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

यहाँ, यदि पता शून्य है, तो आपको NullReferenceException मिल जाएगी।

इसलिए, एक अभ्यास के रूप में हमें हमेशा ऐसी वस्तुओं में संपत्तियों तक पहुंचने से पहले (विशेष रूप से सामान्य में) अशक्त जांच का उपयोग करना चाहिए

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception

-3

यह मूल रूप से अशक्त संदर्भ अपवाद है । जैसा कि Microsoft बताता है-

जब आप किसी ऐसे प्रकार के सदस्य तक पहुँचने का प्रयास करते हैं, जिसका मान शून्य है, तो NullReferenceException अपवाद को फेंक दिया जाता है।

इसका क्या मतलब है?

इसका मतलब है कि यदि कोई भी सदस्य जो कोई मूल्य नहीं रखता है और हम उस सदस्य को कुछ कार्य करने के लिए बना रहे हैं, तो सिस्टम निस्संदेह एक संदेश को टॉस करेगा और कहेगा-

"अरे रुको, उस सदस्य के पास कोई मूल्य नहीं है इसलिए यह उस कार्य को नहीं कर सकता है जिसे आप इसे सौंप रहे हैं।"

अपवाद खुद कहता है कि कुछ संदर्भित किया जा रहा है, लेकिन जिसका मूल्य निर्धारित नहीं किया जा रहा है। तो यह दर्शाता है कि यह केवल संदर्भ प्रकारों का उपयोग करते समय होता है क्योंकि मान प्रकार गैर-अशक्त होते हैं।

यदि हम मान प्रकार के सदस्यों का उपयोग कर रहे हैं तो NullReferenceException नहीं होगी।

class Program
{
    static void Main(string[] args)
    {
        string str = null;
        Console.WriteLine(str.Length);
        Console.ReadLine();
    }
}

उपरोक्त कोड सरल स्ट्रिंग दिखाता है जिसे एक शून्य मान के साथ सौंपा गया है ।

अब, जब मैं स्ट्रिंग की लंबाई प्रिंट करने का प्रयास str , मैं मिलता है प्रकार के 'System.NullReferenceException' एक अनियंत्रित अपवाद घटित संदेश क्योंकि सदस्य str अशक्त की ओर इशारा करते है और वहाँ बातिल के किसी भी लम्बाई नहीं हो सकता।

' NullReferenceException ' तब भी होती है जब हम किसी संदर्भ प्रकार को तुरंत लिखना भूल जाते हैं।

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

class Program
{
    static void Main(string[] args)
    {
        MyClass1 obj;
        obj.foo();  //Use of unassigned local variable 'obj'
    }
}

public class MyClass1
{
    internal void foo()
    {
        Console.WriteLine("hello from foo");

    }
}

उपरोक्त कोड के लिए कंपाइलर एक त्रुटि उठाता है कि वेरिएबल ओबीज अनसाइनड है जो दर्शाता है कि हमारे वेरिएबल में शून्य मान या कुछ भी नहीं है। उपरोक्त कोड के लिए कंपाइलर एक त्रुटि उठाता है कि वेरिएबल ओबीज अनसाइनड है जो दर्शाता है कि हमारे वेरिएबल में शून्य मान या कुछ भी नहीं है।

ऐसा क्यों होता है?

  • NullReferenceException ऑब्जेक्ट के मान की जाँच नहीं करने के लिए हमारी गलती के कारण उत्पन्न होती है। हम अक्सर कोड विकास में अनियंत्रित वस्तु मूल्यों को छोड़ देते हैं।

  • यह तब भी उठता है जब हम अपनी वस्तुओं को पलटना भूल जाते हैं। तरीकों, गुणों, संग्रह आदि का उपयोग करना जो अशक्त मूल्यों को वापस कर सकते हैं या सेट कर सकते हैं, इस अपवाद का कारण भी हो सकता है।

इससे कैसे बचा जा सकता है?

इस प्रसिद्ध अपवाद से बचने के विभिन्न तरीके और तरीके हैं:

  1. स्पष्ट जाँच: हमें वस्तुओं, गुणों, विधियों, सरणियों और संग्रह की जाँच करने की परंपरा का पालन करना चाहिए, चाहे वे शून्य हों। यह बस सशर्त बयानों का उपयोग करके लागू किया जा सकता है, जैसे कि-इफ-इफ-अगर आदि।

  2. अपवाद हैंडलिंग: इस अपवाद को प्रबंधित करने के महत्वपूर्ण तरीकों में से एक। सरल कोशिश-कैच-अंततः ब्लॉकों का उपयोग करके हम इस अपवाद को नियंत्रित कर सकते हैं और इसका लॉग भी बनाए रख सकते हैं। यह तब बहुत उपयोगी हो सकता है जब आपका एप्लिकेशन प्रोडक्शन स्टेज पर हो।

  3. अशक्त संचालक: वस्तुओं, चरों, संपत्तियों और क्षेत्रों में मूल्यों को स्थापित करते समय अशक्त संचालक संचालक और अशक्त सशर्त संचालकों को भी काम में लिया जा सकता है।

  4. डिबगर: डेवलपर्स के लिए, हमारे पास डीबगिंग का बड़ा हथियार है। अगर हम विकास के चेहरे के दौरान NullReferenceException का सामना करते हैं तो हम अपवाद के स्रोत तक पहुंचने के लिए डीबगर का उपयोग कर सकते हैं।

  5. इन-बिल्ट विधि: सिस्टम विधियाँ जैसे GetValueOrDefault (), IsNullOrWhiteSpace () और IsNullorEmpty () नल के लिए जाँच करता है और यदि कोई शून्य मान है तो डिफ़ॉल्ट मान असाइन करें।

यहां पहले से ही कई अच्छे जवाब हैं। आप मेरे ब्लॉग पर उदाहरणों के साथ अधिक विस्तृत विवरण भी देख सकते हैं ।

आशा है कि यह भी मदद करता है!


आपने मूल रूप से उस ब्लॉग पोस्ट के आधे हिस्से को कॉपी किया है और कुछ भी नया नहीं जोड़ा है जो मौजूदा उत्तरों को संबोधित नहीं करता है।
कोडकेस्टर

@codecaster क्या यह कहा जाता है कि जब आप अपने स्वयं के ब्लॉग से सारांश लिखते हैं तो उसे कॉपी करना होता है। मुझे पता है कि मेरे उत्तर में कुछ भी नया नहीं है और कुछ भी नया नहीं है, जो पिछले उत्तर में नहीं है, लेकिन मैं और अधिक परिष्कृत तरीके से योगदान करना चाहता हूं और दूसरों को मेरे समझने के तरीके को समझने देता हूं। किसी एक व्यक्ति की मदद करने पर भी खुशी होगी। सद्भाव।
वसीम

-4

अगर किसी को बिल्ड को सेव या कंपेयर करने के दौरान यह मैसेज मिल रहा है, तो बस सभी फाइलों को बंद कर दें और फिर किसी फाइल को कंपाइल करके सेव करें।

मेरे लिए इसका कारण यह था कि मैंने फ़ाइल का नाम बदल दिया था और पुरानी फ़ाइल अभी भी खुली हुई थी।

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