একটি নুলারফেরান এক্সসেপশন কী এবং আমি কীভাবে এটি ঠিক করব?


1875

আমার কিছু কোড রয়েছে এবং যখন এটি কার্যকর হয়, এটি একটি নিক্ষেপ করে NullReferenceExceptionবলে:

অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি।

এর অর্থ কী এবং এই ত্রুটিটি ঠিক করতে আমি কী করতে পারি?


ভিএস 2017 এর ব্যতিক্রম সহায়ক সহায়ক এই ব্যতিক্রমটির কারণ নির্ণয় করতে আরও সহায়ক হবে - ব্লগস.এমএসএনএন.মাইক্রোসফট. / ভিসুয়ালস্টুডিও / ২০১/ / ১১ / ২৮ / নিউ এক্সেপশন হেল্পারের অধীনে ।
জেভ স্পিটজ

প্রিয় ভবিষ্যতের দর্শনার্থীরা, এই প্রশ্নের উত্তরগুলি সমানভাবে একটি আর্গুমেন্টনাল এক্সসেপশনে প্রয়োগ হয় । যদি আপনার প্রশ্নটির সদৃশ হয়ে থাকে এবং আপনি কোনও এএনইর সম্মুখীন হয়ে থাকেন তবে দয়া করে ডিবাগ করার উত্তরগুলির দিকনির্দেশগুলি অনুসরণ করুন এবং আপনার সমস্যার সমাধান করুন।

@ যদি কেবল কোনও পরামিতি হিসাবে নাল পাস করা হয় তবে এএনই হওয়া উচিত। যদি কোনও এএনই প্রশ্নটির ডুপ্লিকেট হিসাবে বন্ধ হয়ে যায় তবে আপনি উদাহরণ দিতে পারেন?
জন স্যান্ডার্স 21

এটি মেটাতে এসেছিল, তবে আমাকে লিঙ্কটির জন্য খনন করতে হবে। তবে এই মন্তব্য হিসাবে, একটি এএনই কেবল একটি এনআরই তবে কেউ একটি প্রাকৃত চেক যুক্ত করেছেন এবং আপনি কমপক্ষে নালটি কী তা ঠিক জানেন (যুক্তির নামটি সরবরাহ করা হয়েছে), সুতরাং স্ট্রেট আপ এনআরইয়ের চেয়ে নির্ণয় করা কিছুটা সহজ।

উত্তর:


2415

কারণটা কি?

শেষের সারি

আপনি এমন কিছু ব্যবহার করার চেষ্টা করছেন যা null(বা Nothingভিবি.এনইটি তে) রয়েছে। এর অর্থ আপনি এটি সেট করেছেন nullবা আপনি এটিকে কখনই সেট করেন না।

অন্য কিছুর মত, nullচারপাশে পাস হয়ে যায়। যদি হয়null পদ্ধতি "একটি", এটা হতে পারে যে পদ্ধতি "বি" একটি পাস null থেকে পদ্ধতি "একজন"।

null বিভিন্ন অর্থ হতে পারে:

    1. অবজেক্ট ভেরিয়েবলগুলি যা অবিশ্রুত এবং তাই কিছুই না। এই ক্ষেত্রে, আপনি যদি এই ধরণের অবজেক্টগুলির বৈশিষ্ট্য বা পদ্ধতিগুলি অ্যাক্সেস করেন তবে এটি a NullReferenceException
    1. বিকাশকারী কোনও অর্থবহ মান উপলব্ধ নেই তা বোঝাতে ইচ্ছাকৃতভাবে ব্যবহার করছেন nullনোট করুন যে সি # এর ভেরিয়েবলগুলির জন্য নলাবদ্ধ ডেটাটাইপগুলির ধারণা রয়েছে (যেমন ডাটাবেস টেবিলগুলিতে নমনীয় ক্ষেত্র থাকতে পারে) - nullএতে কোনও মান সঞ্চিত নেই তা নির্দেশ করার জন্য আপনি তাদেরকে নির্ধারিত করতে পারেন , উদাহরণস্বরূপ int? a = null;যেখানে প্রশ্ন চিহ্নটি ইঙ্গিত করে যে এটি নালকে সংরক্ষণ করার অনুমতি দেয় পরিবর্তনশীল a। আপনি এটি if (a.HasValue) {...}বা তার সাথে যাচাই করতে পারেন if (a==null) {...}aএই উদাহরণের মতো নুলযোগ্য ভেরিয়েবলগুলি a.Valueসুস্পষ্টভাবে বা সাধারণ হিসাবেও সাধারণভাবে অ্যাক্সেসের অনুমতি দেয় a
      নোট করুন যে এর মাধ্যমে অ্যাক্সেস করা যদি হয় তবে a.Valueএকটি InvalidOperationExceptionপরিবর্তে ছুড়ে দেয়NullReferenceExceptionanull- আপনার আগে চেক করা উচিত, অর্থাত্ যদি আপনার আর একটি অন-অবিচল ভেরিয়েবল থাকে 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

যদি রেফ 1 বা রেফ 2 বা রেফ 3 নাল হয়, তবে আপনি একটি পাবেন 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.

জেগড অ্যারে

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 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;

এএসপি.নেট পৃষ্ঠা জীবনচক্র:

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();

এএসপি.নেট এমভিসি খালি দেখার মডেলগুলি

ব্যতিক্রম ঘটে যখন একটি সম্পত্তি উল্লেখ তাহলে @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কন্ট্রোল 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নিজেই নাল হয়) ফেরত দেয়। সুতরাং যে সচেতন হতে হবে।

লিনকিউ FirstOrDefault()এবংSingleOrDefault()

কিছু না থাকলে প্লেইন সংস্করণ First()এবং Single()ব্যতিক্রম নিক্ষেপ করুন। "অরডিফল্ট" সংস্করণগুলি সেই ক্ষেত্রে শূন্য হয়। সুতরাং যে সচেতন হতে হবে।

প্রতিটির জন্য, প্রত্যেকটির জন্য

foreachনাল সংগ্রহের পুনরাবৃত্তি করার চেষ্টা করার সময় আপনি নিক্ষেপ করেন। সাধারণত nullসংগ্রহগুলি ফেরত দেওয়ার পদ্ধতিগুলি থেকে অপ্রত্যাশিত ফলাফলের ফলে ঘটে ।

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

আরও বাস্তব উদাহরণ - এক্সএমএল ডকুমেন্ট থেকে নোডগুলি নির্বাচন করুন। নোড পাওয়া না গেলে তবে ছুঁড়ে ফেলা হবে তবে প্রাথমিক ডিবাগিং দেখায় যে সমস্ত বৈশিষ্ট্য বৈধ:

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

নাল কোলেসিং অপারেটর ব্যবহার করুন: ??[সি #] বা If()[ভিবি]।

যখন একটি 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] অ্যারেগুলির জন্য (সি # 6 এবং ভিবি। নেট 14 এ উপলব্ধ):

এটিকে কখনও কখনও নিরাপদ নেভিগেশন বা এলভিস (তার আকারের পরে) অপারেটরও বলা হয়। অপারেটরের বাম দিকের অভিব্যক্তিটি যদি শূন্য হয় তবে ডান দিকটি মূল্যায়ন করা হবে না এবং পরিবর্তে নালটি ফিরে আসবে। এর অর্থ এইরকম কেস:

var title = person.Title.ToUpper();

যদি ব্যক্তির কোনও শিরোনাম না থাকে তবে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে কারণ এটি ToUpperনাল মান সহ কোনও সম্পত্তি আহ্বান করার চেষ্টা করছে ।

ভিতরে C# 5এবং নীচে, এগুলি রক্ষা করা যেতে পারে:

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

এখন শিরোনাম ভেরিয়েবল ব্যতিক্রম ছোঁড়ার পরিবর্তে নਾਲ হবে। সি # 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>উপাদানটি প্রদান করে।

নাল প্রসঙ্গ ব্যবহার করুন (সি # 8 এ উপলব্ধ):

চালু C# 8আছে নাল প্রসঙ্গ এবং nullable রেফারেন্স ধরনের ভেরিয়েবল উপর স্ট্যাটিক বিশ্লেষণ সঞ্চালন এবং যদি একটি মান সম্ভাব্য নাল হতে পারে বা নাল জন্য সেট করা হয়েছে একটি কম্পাইলার সতর্কবার্তা প্রদান করে। নালযোগ্য রেফারেন্স ধরণগুলি প্রকারগুলিকে স্পষ্টভাবে শূন্য করার অনুমতি দেয়।

Nullableআপনার csprojফাইলের এলিমেন্টটি ব্যবহার করে কোনও প্রজেক্টের জন্য অযোগ্য টিকা রচনার প্রসঙ্গ এবং অযোগ্য সতর্কতা প্রসঙ্গে সেট করা যেতে পারে । এই উপাদানটি কনফিগার করে যে কীভাবে সংকলক প্রকারের nlalability ব্যাখ্যা করে এবং কী সতর্কতা উত্পন্ন হয়। বৈধ সেটিংস হ'ল:

  • সক্ষম করুন: nullable টীকা প্রসঙ্গে সক্ষম করা হয়। অযোগ্য সতর্কতা প্রসঙ্গে সক্ষম করা হয়েছে। একটি রেফারেন্স ধরণের ভেরিয়েবল, উদাহরণস্বরূপ স্ট্রিং অ-শুল্কযোগ্য। সমস্ত নালিয়াবলীর সতর্কতা সক্ষম করা আছে।
  • অক্ষম করুন: nullaable টীকা প্রসঙ্গে অক্ষম করা হয়। অযোগ্য সতর্কতা প্রসঙ্গে অক্ষম করা আছে। একটি রেফারেন্স টাইপের ভেরিয়েবলগুলি সি # এর আগের সংস্করণগুলির মতোই বিস্মৃত। সমস্ত নালিয়াবলীর সতর্কতাগুলি অক্ষম।
  • নিরাপদে: নোল টিকা টেক্সট প্রসঙ্গে সক্ষম করা হয়েছে। অযোগ্য সতর্কতা প্রসঙ্গটি নিরাপদে। একটি রেফারেন্স প্রকারের ভেরিয়েবলগুলি অগ্রহণযোগ্য। সমস্ত সুরক্ষা nullability সতর্কতা সক্ষম করা হয়েছে।
  • সতর্কতা: অকার্যকর টীকা প্রসঙ্গে অক্ষম করা আছে। অযোগ্য সতর্কতা প্রসঙ্গে সক্ষম করা হয়েছে। একটি রেফারেন্স প্রকারের ভেরিয়েবলগুলি বিস্মৃত। সমস্ত নালিয়াবলীর সতর্কতা সক্ষম করা আছে।
  • SafeonlyWarnings: nullable টীকা প্রসঙ্গে অক্ষম করা আছে। অযোগ্য সতর্কতা প্রসঙ্গটি নিরাপদে। একটি রেফারেন্স প্রকারের ভেরিয়েবলগুলি বিস্মৃত। সমস্ত সুরক্ষা nullability সতর্কতা সক্ষম করা হয়েছে।

নালযোগ্য রেফারেন্স টাইপটি একই সিনট্যাক্স ব্যবহার করে নুলযোগ্য মান ধরণের হিসাবে নোট করা হয়: একটি ?ভেরিয়েবলের ধরণের সাথে যুক্ত হয়।

পুনরাবৃত্তকারীগুলিতে ডিবাগিং এবং নাল ডেরেফগুলি ঠিক করার জন্য বিশেষ কৌশল

C#"পুনরাবৃত্তকারী ব্লক" (অন্য কয়েকটি জনপ্রিয় ভাষায় "জেনারেটর" বলা হয়) সমর্থন করে। নাল ডেরিফারেন্স ব্যতিক্রমগুলি স্থগিতাদেশ কার্যকর হওয়ার কারণে পুনরুক্তিকারী ব্লকগুলিতে ডিবাগ করা বিশেষত জটিল y

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#নামটি থেকে বোঝা যায় যে একটি "অনিরাপদ" মোড রয়েছে যা অত্যন্ত বিপজ্জনক কারণ মেমরির সুরক্ষা এবং টাইপ সুরক্ষা সরবরাহকারী সাধারণ সুরক্ষা ব্যবস্থা প্রয়োগ করা হয় না। মেমরি কীভাবে কাজ করে তা সম্পর্কে আপনার কাছে গভীর এবং গভীর ধারণা না থাকলে আপনার অনিরাপদ কোডটি লেখা উচিত নয়

অনিরাপদ মোডে আপনার দুটি গুরুত্বপূর্ণ তথ্য সম্পর্কে সচেতন হওয়া উচিত:

  • একটি নাল পয়েন্টারকে ডিফারেন্স করা নাল রেফারেন্সকে dereferences হিসাবে একই ব্যতিক্রম উত্পাদন করে
  • একটি অবৈধ নন-নাল পয়েন্টারকে অবজ্ঞা করা কিছু পরিস্থিতিতে এই ব্যতিক্রমটি তৈরি করতে পারে

এটি কেন তা বোঝার জন্য এটি বুঝতে সহায়তা করে যে কীভাবে .NET প্রথমে নাল ডিসেফারেন্স ব্যতিক্রম তৈরি করে। (এই বিবরণগুলি উইন্ডোজ চলমান .NET- এ প্রযোজ্য; অন্যান্য অপারেটিং সিস্টেমগুলি অনুরূপ প্রক্রিয়া ব্যবহার করে))

মেমরি ভার্চুয়ালাইজড হয় Windows; প্রতিটি প্রক্রিয়া অপারেটিং সিস্টেম দ্বারা ট্র্যাক করা মেমরির অনেক "পৃষ্ঠাগুলির" একটি ভার্চুয়াল মেমরি স্থান পায়। মেমোরির প্রতিটি পৃষ্ঠায় পতাকা লাগানো থাকে যা এটি কীভাবে ব্যবহার করা যেতে পারে তা নির্ধারণ করে: পাঠানো, এতে লিখিত, সম্পাদন করা ইত্যাদি। সর্বনিম্ন পৃষ্ঠা "যদি কখনও কোন ভাবে ব্যবহার করার সময় একটি ত্রুটি উৎপন্ন" হিসেবে চিহ্নিত করা হয়।

একটি নাল পয়েন্টার এবং একটি নাল রেফারেন্স C#উভয়ই অভ্যন্তরীণভাবে শূন্য সংখ্যা হিসাবে উপস্থাপিত হয়, এবং সুতরাং এটির সাথে সম্পর্কিত মেমরি স্টোরেজটিতে এটিকে মূল্যহ্রাস করার কোনও প্রচেষ্টা অপারেটিং সিস্টেমকে ত্রুটি তৈরি করার কারণ করে। .NET রানটাইম এরপরে এই ত্রুটিটি সনাক্ত করে এবং এটিকে নাল ডিरेফারেন্স ব্যতিক্রমে রূপান্তরিত করে।

একারণে নাল পয়েন্টার এবং নাল রেফারেন্স উভয়কেই সমাহার করা একই ব্যতিক্রম ঘটায়।

দ্বিতীয় দফার কী হবে? ভার্চুয়াল মেমরির সর্বনিম্ন পৃষ্ঠায় আসা যে কোনও অবৈধ পয়েন্টারকে ডিফার করা একই অপারেটিং সিস্টেম ত্রুটির কারণ হয়ে দাঁড়ায় এবং এর ফলে একই ব্যতিক্রম ঘটে।

কেন এটা বোঝা যায়? ঠিক আছে, ধরুন আমাদের দুটি কাঠামো সমন্বিত একটি কাঠামো আছে এবং একটি অব্যবহৃত পয়েন্টার নাল সমান। যদি আমরা স্ট্রাক্টে দ্বিতীয় ইনট্রিকে অবজ্ঞার চেষ্টা করি, তবে CLRএটি শূন্যের স্থানে স্টোরেজ অ্যাক্সেস করার চেষ্টা করবে না; এটি চারটি স্থানে স্টোরেজ অ্যাক্সেস করবে। কিন্তু কথাটি এই ডি-রেফারেন্স কারণ আমরা ঐ ঠিকানায় পাচ্ছেন একটি নাল মাধ্যমে নাল।

আপনি যদি অনিরাপদ কোড নিয়ে কাজ করছেন এবং আপনি যদি একটি নাল ডিসেফারেন্স ব্যতিক্রম পেয়ে থাকেন তবে কেবল সচেতন হন যে আপত্তিকর পয়েন্টারটি নালার দরকার নেই। এটি সর্বনিম্ন পৃষ্ঠায় যে কোনও অবস্থান হতে পারে এবং এই ব্যতিক্রমটি উত্পাদিত হবে।


55
হতে পারে এটি বোবা মন্তব্য তবে এই সমস্যাটি এড়ানোর প্রথম এবং সর্বোত্তম উপায় হ'ল অবজেক্টটি আরম্ভ করা? আমার জন্য যদি এই ত্রুটি দেখা দেয় তবে এটি সাধারণত কারণ আমি অ্যারের উপাদানটির মতো কিছু শুরু করতে ভুলে গিয়েছিলাম। আমি মনে করি বিষয়টিকে নাল হিসাবে সংজ্ঞায়িত করা এবং তারপরে এটি উল্লেখ করা খুব কম সাধারণ far বর্ণনার সংলগ্ন প্রতিটি সমস্যা সমাধানের উপায় দিন Maybe এখনও একটি ভাল পোস্ট।
জেপিকে 20'14

30
যদি কোনও বস্তু না থাকে, তবে কোনও পদ্ধতি বা সম্পত্তি থেকে ফেরতের মান কী হয়?
জন স্যান্ডার্স

6
বই / লেখকের উদাহরণটি কিছুটা অদ্ভুত .... কীভাবে এটি সংকলন করে? ইন্টেলিজেন্স এমনকি কীভাবে কাজ করে? এটি কি আমি কম্পুটারের সাথে ভাল নই ...

5
@ উইল: আমার শেষ সম্পাদনা সাহায্য করে? যদি তা না হয় তবে দয়া করে আপনি যা সমস্যা হিসাবে দেখছেন সে সম্পর্কে আরও সুস্পষ্ট হন।
জন স্যান্ডার্স

6
@ জনসন্ডার্স ওহ, না, দুঃখিত, আমি এর অবজেক্ট ইনিশিয়ালাইজার সংস্করণটি বুঝিয়েছি। new Book { Author = { Age = 45 } };অভ্যন্তরীণ সূচনাটি কীভাবে এমনকি কীভাবে হয় ... আমি এমন কোনও পরিস্থিতির কথা ভাবতে পারি না যেখানে অভ্যন্তরীণ উদ্যোগ কখনই কাজ করবে, তবু এটি সংকলন এবং বুদ্ধিদীপ্ত কাজ করে ... স্ট্রাক্ট না থাকলে?

311

নাল রেফারেন্স ব্যতিক্রম - ভিজ্যুয়াল বেসিক

NullReference Exceptionজন্য ভিসুয়াল বেসিক মধ্যে এক থেকে কোন পার্থক্য নাই সি # । সর্বোপরি, তারা উভয়ই .NET ফ্রেমওয়ার্কে সংজ্ঞায়িত একই ব্যতিক্রমের প্রতিবেদন করছে যা তারা উভয়ই ব্যবহার করে। ভিজ্যুয়াল বেসিকের অনন্য কারণগুলি বিরল (সম্ভবত কেবল একটি)।

এই উত্তরটি ভিজ্যুয়াল বেসিক পদগুলি, বাক্য গঠন এবং প্রসঙ্গ ব্যবহার করবে। ব্যবহৃত উদাহরণগুলি প্রচুর অতীত স্ট্যাক ওভারফ্লো প্রশ্ন থেকে আসে। পোস্টে প্রায়শই দেখা যায় এমন ধরণের পরিস্থিতি ব্যবহার করে প্রাসঙ্গিকতা সর্বাধিককরণের জন্য এটি । যাদের প্রয়োজন হতে পারে তাদের জন্য আরও কিছুটা ব্যাখ্যা প্রদান করা হয়েছে। আপনার অনুরূপ উদাহরণ খুব সম্ভবত এখানে তালিকাভুক্ত করা হয়।

বিঃদ্রঃ:

  1. এটি ধারণা-ভিত্তিক: আপনার প্রকল্পে পেস্ট করার কোনও কোড নেই। একটি NullReferenceException(এনআরই) কী কী কারণে হয়, এটি কীভাবে সন্ধান করা যায়, কীভাবে এটি ঠিক করা যায় এবং কীভাবে এড়ানো যায় তা বুঝতে আপনাকে সহায়তা করার উদ্দেশ্যে এটি করা হয়েছে। একটি এনআরই এর অনেক কারণ হতে পারে তাই এটি আপনার একমাত্র মুখোমুখি হওয়ার সম্ভাবনা নেই।
  2. উদাহরণ (স্ট্যাক ওভারফ্লো পোস্টগুলি থেকে) সর্বদা প্রথম স্থানে কিছু করার সর্বোত্তম উপায় প্রদর্শন করে না।
  3. সাধারণত, সবচেয়ে সহজ প্রতিকার ব্যবহৃত হয়।

বেসিক অর্থ

" অবজেক্টটির কোনও উদাহরণে সেট করা হয়নি" বার্তাটির অর্থ আপনি কোনও অবজেক্টটি ব্যবহার করার চেষ্টা করছেন যা আরম্ভ করা হয়নি। এটি এর মধ্যে একটিতে সিদ্ধ হয়:

  • আপনার কোডটি একটি অবজেক্ট ভেরিয়েবল হিসাবে ঘোষণা করেছে, তবে এটি এটি আরম্ভ করে নি (উদাহরণ তৈরি করুন বা এটি ' ইনস্ট্যান্টিয়েট করুন ')
  • আপনার কোড ধরে নেওয়া এমন কিছু যা কোনও বস্তুর সূচনা করবে, তা হয়নি
  • সম্ভবত, অন্যান্য কোড অকাল আগে অবধি ব্যবহার করা অবধি অবৈধ

কারণ সন্ধান করা

যেহেতু সমস্যাটি কোনও অবজেক্ট রেফারেন্স যা হ'ল Nothing, উত্তরটি হ'ল কোনটি একটি তা খুঁজে বের করার জন্য তাদের পরীক্ষা করা। তারপরে এটি কেন প্রাথমিক করা হয়নি তা নির্ধারণ করুন। বিভিন্ন ভেরিয়েবলের উপর মাউস ধরে রাখুন এবং ভিজ্যুয়াল স্টুডিও (ভিএস) তাদের মানগুলি দেখায় - অপরাধী হবে Nothing

আইডিই ডিবাগ প্রদর্শন

আপনার প্রাসঙ্গিক কোড থেকে যে কোনও ট্রাই / ক্যাচ ব্লকগুলি মুছে ফেলা উচিত, বিশেষত এমনগুলি যেখানে ক্যাচ ব্লকে কিছুই নেই। এটি আপনার কোডটিকে ক্রাশ করার কারণ যখন এটি কোনও অবজেক্টটি ব্যবহার করার চেষ্টা করে Nothingআপনি যা চান এটি এটি কারণ এটি সমস্যার সঠিক অবস্থানটি সনাক্ত করতে এবং আপনাকে এটির কারণটি সনাক্ত করার অনুমতি দেয়।

একটি MsgBoxক্যাচ যা প্রদর্শন করে Error while...তাতে খুব একটা সহায়ক হবে। এই পদ্ধতিটি খুব খারাপ স্ট্যাক ওভারফ্লো প্রশ্নগুলির দিকে পরিচালিত করে , কারণ আপনি প্রকৃত ব্যতিক্রম, বস্তুর সাথে জড়িত বা এমনকি কোডের লাইনটি যেখানে ঘটে তা বর্ণনা করতে পারবেন না।

আপনি নিজের বস্তুগুলি পরীক্ষা করতে Locals Window( ডিবাগ -> উইন্ডোজ -> স্থানীয় ) ও ব্যবহার করতে পারেন ।

সমস্যাটি কী এবং কোথায় তা জানার পরে সাধারণত কোনও নতুন প্রশ্ন পোস্ট করার চেয়ে সমাধান করা মোটামুটি সহজ এবং দ্রুত।

আরো দেখুন:

উদাহরণ এবং প্রতিকার

ক্লাস অবজেক্টস / একটি ইনস্ট্যান্স তৈরি করা

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

সমস্যাটি হ'ল Dimক্যাশ-রেজিস্টার বস্তু তৈরি করে না ; এটি কেবলমাত্র এই ধরণের নামের একটি ভেরিয়েবল ঘোষণা করে 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 কারণ

ভিজ্যুয়াল বেসিক বারবার ব্যবহার করে প্রক্রিয়াটি পরিষ্কার করার চেষ্টা করে New: Newঅপারেটর ব্যবহার করে একটি নতুন অবজেক্ট তৈরি হয় এবং কলগুলি Sub New- কনস্ট্রাক্টর - যেখানে আপনার অবজেক্টটি অন্য কোনও সূচনা করতে পারে।

পরিষ্কার হতে, Dim(বা Private) কেবল একটি ভেরিয়েবল এবং এর ঘোষণা করে Typeব্যাপ্তি তা সমগ্র মডিউল / বর্গ জন্য বিদ্যমান বা একটি পদ্ধতি স্থানীয় হল - - ভেরিয়েবলের দ্বারা নির্ধারিত হয় যেখানে এটি ঘোষিত হয়। Private | Friend | Publicঅ্যাক্সেস স্তর সংজ্ঞা দেয়, স্কোপ নয় ।

আরও তথ্যের জন্য, দেখুন:


অ্যারেগুলির

অ্যারেগুলিও তাত্ক্ষণিকভাবে আবশ্যক:

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) {}

দ্রষ্টব্য: ভিএস ২০১০ থেকে শুরু করে, যখন আক্ষরিক ব্যবহার করে স্থানীয় অ্যারে শুরু করা হয় এবং Option Infer, As <Type>এবং Newউপাদানগুলি alচ্ছিক:

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}

উদাহরণ: শ্রেণি সামগ্রীর অ্যারে ray

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একবারে ....) ব্যবহারে রয়েছে। দ্রষ্টব্য: আপনি কোন ডেটা সরবরাহকারীর ব্যবহার করছেন তা বিবেচ্য নয় - মাইএসকিউএল, এসকিউএল সার্ভার, ওলেডিবি ইত্যাদি - ধারণাগুলি একই রকম।

উদাহরণ 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স্থানীয় পরিবর্তনশীল, তাই IDE আপনাকে সতর্ক করে যে এটি হতে পারে:

চিত্র

যখন মডিউল / শ্রেণি স্তরের ভেরিয়েবল হিসাবে ঘোষিত হয়, যেমনটি ঘটেছে বলে মনে হয় 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বনাম EmployeeDataTable"কর্মচারী" নামে কোনও নাম তৈরি করা হয়নি, সুতরাং NullReferenceExceptionএটির অ্যাক্সেস করার চেষ্টা করে একটি ফলাফল। আর একটি সম্ভাব্য সমস্যা অনুমান করছে যে এটি হবে Itemsযা এসকিউএল-এর যেখানে যেখানে একটি বিধি অন্তর্ভুক্ত রয়েছে তা নাও হতে পারে।

প্রতিকার

যেহেতু এটি একটি টেবিল ব্যবহার করে তাই 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(এবং যদি) পরে মূল্যায়ন করে একবারে অবজেক্টগুলিতে 'এক স্তর' সুরক্ষিতভাবে 'ড্রিল' করতে দেয় andmyFoo বৈধ হওয়ার জন্য নির্ধারিত হয় । জটিল অবজেক্ট কোডিংয়ের সময় অবজেক্ট চেইন বা পাথগুলি বেশ দীর্ঘ হতে পারে:

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 এবং এসকিউএল পরামিতি):

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

এটি একটি এনআরই পাওয়ার মোটামুটি সাধারণ উপায়। সি # তে, কীভাবে এটি কোডিং করা হয়েছে তার উপর নির্ভর করে IDE এটি রিপোর্ট করবেControls যা বর্তমান প্রসঙ্গে নেই বা "স্থিতিশীল সদস্যকে উল্লেখ করতে পারে না"। সুতরাং, কিছুটা হলেও, এটি একটি ভিবি-কেবল পরিস্থিতি। এটি জটিলও কারণ এটির ফলে ব্যর্থতা ক্যাসকেড হতে পারে।

অ্যারে এবং সংগ্রহগুলি এভাবে শুরু করা যায় না। এই আরম্ভের কোডটি কনস্ট্রাক্টর তৈরি করার আগেForm বা চালিত হবেControls । ফলস্বরূপ:

  • তালিকা এবং সংগ্রহটি খালি থাকবে
  • অ্যারেতে নথিংয়ের পাঁচটি উপাদান থাকবে
  • somevarনিয়োগ একটি তাৎক্ষণিক NRE পরিণাম ডেকে আনবে কারণ কিছুই নেই .Textসম্পত্তি

অ্যারে উপাদানগুলি পরে রেফারেন্স করার ফলে একটি এনআরই হবে। যদি আপনি এটি করেন Form_Load, কোনও বিজোড় বাগের কারণে, আইডিই ব্যতিক্রম ঘটলে এটি রিপোর্ট করতে পারে না । আপনার কোডটি অ্যারে ব্যবহার করার চেষ্টা করার পরে ব্যতিক্রমটি পপ আপ হবে । এই "নীরব ব্যতিক্রম" এই পোস্টে বিস্তারিত রয়েছে । আমাদের উদ্দেশ্যে, মূলটি হ'ল যখন কোনও ফর্ম তৈরি করার সময় বিপর্যয়কর কিছু ঘটে ( 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; তারা সেই প্যানেল বা গ্রুপবক্সের নিয়ন্ত্রণের সংগ্রহে থাকবে। যখন নিয়ন্ত্রণের নাম ভুল বানান করা হয় ( "TeStBox2") তখনও কোনও নিয়ন্ত্রণ ফিরে আসবে না । এই ক্ষেত্রে,Nothing আবার সেই অ্যারে উপাদানগুলিতে পুনরায় সংরক্ষণ করা হবে এবং আপনি যখন রেফারেন্স দেওয়ার চেষ্টা করবেন তখন একটি এনআরই ফলাফল হবে।

এগুলি এখন সন্ধান করা সহজ হওয়া উচিত যা আপনি জানেন যে আপনি কী সন্ধান করছেন: ভিএস আপনাকে আপনার উপায়গুলির ত্রুটি দেখায়

"বাটন 2" এ থাকে 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' পরে) হয় .ExecuteReaderCatchকিছু না করার পরে , Finallyপরিষ্কার করার চেষ্টা করে, তবে যেহেতু আপনি Closeকোনও নাল DataReaderবস্তু করতে পারেন না , একেবারে নতুনNullReferenceException ফলাফল।

একটি খালি Catchব্লক হ'ল শয়তানের খেলার মাঠ। এই Finallyব্লকে তিনি কেন এনআরই পাচ্ছিলেন তা নিয়ে এই ওপি বিস্মিত হয়েছিল । অন্যান্য পরিস্থিতিতে, খালি খালি এর Catchফলে আরও কিছু প্রবাহিত হতে পারে যা নদীর গভীরতার দিকে চলে যায় এবং সমস্যার জন্য ভুল জায়গায় ভুল জিনিসগুলি দেখার জন্য আপনাকে সময় ব্যয় করতে পারে। (উপরে বর্ণিত "নীরব ব্যতিক্রম" একই বিনোদনের মান সরবরাহ করে))

প্রতিকার

খালি ট্রাই / ক্যাচ ব্লক ব্যবহার করবেন না - কোডটি ক্র্যাশ করুন যাতে আপনি ক) কারণটি সনাক্ত করতে পারেন খ) অবস্থানটি চিহ্নিত করুন এবং গ) সঠিক প্রতিকার প্রয়োগ করুন। বিকাশকারী / বিকাশকারীদের এগুলি ঠিক করার জন্য অনন্যভাবে যোগ্য ব্যক্তি থেকে ব্যতিক্রমগুলি লুকানোর উদ্দেশ্যে নয়।


ডিবিএনল কিছুই নাথিংয়ের মতো নয়

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

IsDBNullফাংশন পরীক্ষা করতে ব্যবহৃত একটি হয় মান সমান System.DBNull: দুটিই MSDN থেকে:

System.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 ...

ডেটাগ্রিডভিউ

ডিজিভিতে পর্যায়ক্রমে কয়েকটি কৌতুক দেখা যায়:

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 - নিউরো থেকে সাবধান থাকুন

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একটি NullReference প্রথমবারের আপনি এটি ব্যবহার হতে পারে। সমাধান একই, কিন্তু হিসাবে সুস্পষ্ট না। বিবেচনা:

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

যেহেতু ভিবি আপনার জন্য সেটিংস পরিচালনা করছে, সংগ্রহটি এটি আরম্ভ করার জন্য এটি আশা করা যুক্তিসঙ্গত। এটি হবে, তবে কেবলমাত্র আপনি যদি পূর্বে সংগ্রহটিতে প্রাথমিক এন্ট্রি যোগ করেছেন (সেটিংস সম্পাদকে)। যেহেতু সংগ্রহটি (আপাতদৃষ্টিতে) কোনও আইটেম যুক্ত করা হয় তখন এটি আরম্ভ করা Nothingহয়, সেটিংস সম্পাদনায় কোনও আইটেম যোগ করার জন্য না থাকলে এটি অবশেষ থাকে ।

প্রতিকার

ফর্মের Loadইভেন্ট হ্যান্ডলারটিতে সেটিংস সংগ্রহের সূচনা করুন , যদি / প্রয়োজন হয়:

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

সাধারণত, Settingsপ্রথমবার অ্যাপ্লিকেশনটি সঞ্চালনের সময় সংগ্রহটি আরম্ভ করা দরকার। একটি বিকল্প প্রতিকার হ'ল প্রকল্প -> সেটিংস | আপনার সংগ্রহে প্রাথমিক মান যুক্ত করা FooBars , প্রকল্পটি সংরক্ষণ করুন, তারপরে জাল মানটি সরান।


গুরুত্বপূর্ণ দিক

আপনি সম্ভবত Newঅপারেটরটি ভুলে গেছেন ।

অথবা

আপনি ধরে নিয়েছেন এমন কিছু আপনার কোডটিতে একটি প্রাথমিক অবজেক্ট ফিরিয়ে দেওয়ার জন্য নির্দ্বিধায় সম্পাদন করবে not

সংকলক সতর্কতা (কখনও) উপেক্ষা করবেন না এবং Option Strict On(সর্বদা) ব্যবহার করুন ।


এমএসডিএন নাল রেফারেন্স ব্যতিক্রম


226

অন্য দৃশ্যাবলীটি হ'ল যখন আপনি কোনও মান প্রকারে কোনও নাল বস্তু নিক্ষেপ করেন । উদাহরণস্বরূপ, নীচের কোড:

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

এটি নিক্ষেপ করবে NullReferenceException কাস্টের উপরে ফেলে দেবে। উপরের নমুনায় এটি বেশ সুস্পষ্ট বলে মনে হয়, তবে এটি আরও "দেরি-বাঁধাই করা" জটিল পরিস্থিতিগুলিতে ঘটতে পারে যেখানে নাল অবজেক্টটি আপনার নিজের নয় এমন কিছু কোড থেকে ফিরে এসেছে এবং কাস্ট উদাহরণটি কিছু স্বয়ংক্রিয় সিস্টেম দ্বারা উত্পন্ন।

এর একটি উদাহরণ ক্যালেন্ডার নিয়ন্ত্রণের সাথে এই সাধারণ এএসপি.নেট বাঁধাইয়ের টুকরা:

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

এখানে, SelectedDateএর - একটি সম্পত্তি আসলে DateTimeটাইপ - এর Calendarওয়েব কন্ট্রোল ধরন, ও বাঁধাই পুরোপুরি কিছু নাল ফিরে আসতে পারে। অন্তর্ভুক্ত এএসপি.এনইটি জেনারেটর কোডের একটি অংশ তৈরি করবে যা উপরের কাস্ট কোডের সমান হবে। এবং NullReferenceExceptionএটি এমন একটি উত্থাপন করবে যা চিহ্নিত করা বেশ কঠিন, কারণ এটি এএসপি.নেট জেনারেট কোডে রয়েছে যা সূক্ষ্ম সংকলন করে ...


7
দুর্দান্ত ধরা এড়াতে ওয়ান-লাইনার উপায়:DateTime x = (DateTime) o as DateTime? ?? defaultValue;
সার্জ শাল্টজ

159

এর অর্থ হ'ল প্রশ্নের মধ্যে পরিবর্তনশীলটি কিছুই দেখায় না। আমি এটি এর মতো তৈরি করতে পারি:

SqlConnection connection = null;
connection.Open();

এটি ত্রুটি ছুঁড়ে ফেলবে কারণ আমি ভেরিয়েবলটি " connection" ঘোষণা করার পরেও এটি কোনও কিছুর প্রতি নির্দেশিত নয়। আমি যখন সদস্যটিকে " Open" কল করার চেষ্টা করি তখন এর সমাধান করার কোনও রেফারেন্স নেই এবং এটি ত্রুটিটি ছুঁড়ে দেবে।

এই ত্রুটি এড়াতে:

  1. আপনি তাদের সাথে কিছু করার চেষ্টা করার আগে সর্বদা আপনার অবজেক্টগুলি আরম্ভ করুন।
  2. আপনি কি নিশ্চিতরূপে বস্তুর নাল কিনা না হন, তাহলে এটা দিয়ে পরীক্ষা object == null

জেটব্রেইনসের পুনঃসূচনা সরঞ্জামটি আপনার কোডের এমন প্রতিটি জায়গা সনাক্ত করবে যেখানে নাল রেফারেন্স ত্রুটির সম্ভাবনা রয়েছে, আপনাকে নাল চেক করার অনুমতি দেয়। এই ত্রুটিটি বাগের এক নম্বর উত্স, আইএমএইচও।


3
জেটব্রেইনসের পুনরায় ভাগকারী সরঞ্জামটি আপনার কোডের প্রতিটি জায়গা শনাক্ত করবে যেখানে নাল রেফারেন্স ত্রুটির সম্ভাবনা রয়েছে। এটি ভুল। সেই সনাক্তকরণ ছাড়াই আমার একটি সমাধান রয়েছে, তবুও কোডটি মাঝে মধ্যে ব্যতিক্রম হয়। আমি সন্দেহ করি যে এটি মাঝেমধ্যে সনাক্ত করা যায় না - তাদের দ্বারা অন্তত - যখন মাল্টিথ্রেডিং জড়িত থাকে তবে আমি আরও মন্তব্য করতে পারি না কারণ আমি এখনও আমার বাগের অবস্থানটি সনাক্ত করতে পারি নি।
j রিভ

তবে কীভাবে এটি সমাধান করবেন যখন নলরফেরেন্সএক্সেপশনটি HttpContext.Current.Responce.C 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

সচেতন হোন যে পরিস্থিতি নির্বিশেষে কারণটি সর্বদা নেট। নেট-এ একই থাকে:

আপনি একটি রেফারেন্স ভেরিয়েবল ব্যবহার করার চেষ্টা করছেন যার মান 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 রানটাইম একটি নালারফেরান এক্সেক্সপশন নিক্ষেপ করবে যখন আপনি এমন কোনও কিছুর উপর ক্রিয়া করার চেষ্টা করবেন যা উপরের কোডটি তাত্ক্ষণিকভাবে হয়নি।

একটি আর্গুমেন্টনাল এক্সসেপশনের তুলনায় যা সাধারণত একটি প্রতিরক্ষামূলক ব্যবস্থা হিসাবে নিক্ষেপ করা হয় যদি কোনও পদ্ধতি প্রত্যাশা করে যে এতে যা পাস হচ্ছে তা শূন্য নয়।

আরও তথ্য সি # নুলারফেরান এক্সেপশন এবং নাল প্যারামিটারে রয়েছে


87

সি # 8.0, 2019 আপডেট করুন: অযোগ্য রেফারেন্স ধরণের

সি # 8.0 nullaable রেফারেন্স ধরণ এবং নন-অযোগ্য রেফারেন্স ধরণের প্রবর্তন করে । সুতরাং একটি নুলারফেরান এক্সসেপশন এড়ানোর জন্য কেবলমাত্র উল্লেখযোগ্য রেফারেন্স প্রকারগুলি অবশ্যই পরীক্ষা করা উচিত ।


আপনি যদি কোনও রেফারেন্স প্রকারের সূচনা না করে থাকেন এবং আপনি এর একটি বৈশিষ্ট্য সেট করতে বা পড়তে চান তবে এটি একটি নালরফেরান এক্সেপশন নিক্ষেপ করবে ।

উদাহরণ:

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
}

নুলারফেরান এক্সসেপশনটি কেন ফেলে দেওয়া হয়েছে তা সম্পূর্ণরূপে বুঝতে, মান ধরণের এবং [রেফারেন্স প্রকারের] [3] এর মধ্যে পার্থক্যটি জানা গুরুত্বপূর্ণ ।

সুতরাং, আপনি যদি মান ধরণের সাথে কাজ করে থাকেন তবে নালরফেরেন্সএক্সেপশনগুলি ঘটতে পারে না । যদিও আপনাকে রেফারেন্সের ধরণের সাথে সতর্কতা অবলম্বন করা দরকার !

নাম উল্লেখ করার সাথে সাথে কেবল রেফারেন্সের ধরণগুলি রেফারেন্স রাখতে পারে বা অক্ষরে অক্ষরে (বা 'নাল') নির্দেশ করতে পারে। যেখানে মান ধরণের সবসময় একটি মান থাকে।

রেফারেন্সের ধরণ (এগুলি অবশ্যই পরীক্ষা করা উচিত):

  • প্রগতিশীল
  • উদ্দেশ্য
  • দড়ি

মান ধরণের (আপনি কেবল এগুলি উপেক্ষা করতে পারেন):

  • সংখ্যার প্রকার
  • ইন্টিগ্রাল টাইপ
  • ভাসমান পয়েন্ট ধরণের
  • দশমিক
  • bool,
  • ব্যবহারকারী সংজ্ঞায়িত স্ট্রাইক

6
-১: যেহেতু প্রশ্নটি "নুলারফেরান এক্সেক্সেশনটি কী", তাই মান ধরণের প্রাসঙ্গিক নয়।
জন স্যান্ডার্স

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বেমানান ধরণের; a এ Carরূপান্তর / কাস্ট করা যায় না Book। যখন এই কাস্ট ব্যর্থ হয়, asফিরে আসে null। এর mybookপরে ব্যবহার করলে কNullReferenceException

সাধারণভাবে, আপনার asনিম্নরূপে একটি castালাই বা ব্যবহার করা উচিত :

আপনি যদি ধরণের রূপান্তরটি সর্বদা সফল হওয়ার প্রত্যাশা করে থাকেন (যেমন, আপনি জানেন যে বস্তুর আগে কী হওয়া উচিত) তবে আপনার একটি কাস্ট ব্যবহার করা উচিত:

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.NullReferencesException: অবজেক্ট রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি। প্রোগ্রামে.মেন ()


1
কত গভীর! আমি কখনই 'নাল' ধ্রুবকটিকে একটি রেফারেন্স মান হিসাবে বিবেচনা করি নি। সুতরাং এইভাবেই সি # বিমূর্তভাবে একটি "নুলপয়েন্টার" হাহ? বি / সি যেমন আমি সি ++ তে স্মরণ করি, একটি এনপিই হ'ল একটি অনির্দিষ্ট পয়েন্টার (যেমন, সি # তে রেফ টাইপ) এর ডিফারেন্সের কারণে ঘটতে পারে যার ডিফল্ট মান এমন একটি ঠিকানা হিসাবে ঘটে যা এই প্রক্রিয়াতে বরাদ্দ না করা হয় (অনেক ক্ষেত্রে এটি 0 হবে, বিশেষত সি ++ এর পরবর্তী সংস্করণগুলিতে যা অটো-ইনিশিয়ালেশন হয়েছিল, যা ওএস-এর সাথে সম্পর্কিত - চ এর সাথে মরে যায় এবং বীওটচ (অথবা কেবল সিগকিল ধরুন ওএস আপনার প্রক্রিয়াটিতে আক্রমণ করে)।
সামিস

64

যদিও কি একটি কারণ NullReferenceExceptions এবং পন্থা এড়ানোর / ঠিক যেমন একটি ব্যতিক্রম অন্যান্য উত্তর নিয়ে আলোচনা করা হয়েছে, কি অনেক প্রোগ্রামার এখনো শেখেনি কিভাবে স্বাধীনভাবে হয় ডিবাগ উন্নয়ন সময় যেমন ব্যতিক্রম।

ভিজ্যুয়াল স্টুডিওতে এটি ভিজ্যুয়াল স্টুডিও ডিবাগারকে সহজেই ধন্যবাদ জানায় ।


প্রথমে নিশ্চিত হয়ে নিন যে সঠিক ত্রুটিটি ধরা পড়ছে - দেখুন কীভাবে আমি ভিএস 2010-এ 'সিস্টেম.নুলআরফেরেন্স এক্সপেশন' ভাঙ্গতে দেব? নোট 1

তারপরে হয় ডিবাগিং (এফ 5) দিয়ে শুরু করুন বা চলমান প্রক্রিয়াতে [ভিএস ডিবাগার] সংযুক্ত করুন । উপলক্ষ্যে এটি ব্যবহারে দরকারী হতে পারে Debugger.Break, যা ডিবাগারটি প্রবর্তন করতে অনুরোধ করবে।

এখন, যখন নালরফেরেন্সএক্সেপশন নিক্ষেপ করা হবে (বা আনহ্যান্ডল করা হয়নি) ডিবাগারটি থামিয়ে দেবে (উপরের নিয়মটি কি মনে আছে?) যে রেখায় ব্যতিক্রম ঘটেছে। কখনও কখনও ত্রুটি চিহ্নিত করা সহজ হবে।

উদাহরণস্বরূপ, নিম্নলিখিত লাইন একমাত্র কোডটি করতে ব্যতিক্রম কারণ যদি myStringমূল্যায়ন নাল করতে। এটি ওয়াচ উইন্ডোটি দেখে বা তাত্ক্ষণিক উইন্ডোতে চালিত অভিব্যক্তিগুলি দ্বারা যাচাই করা যেতে পারে ।

var x = myString.Trim();

নিম্নলিখিত হিসাবে আরও উন্নত ক্ষেত্রে, আপনাকে str1শূন্য ছিল কিনা বা শূন্য ছিল তা নির্ধারণ করার জন্য আপনাকে উপরের কৌশলগুলির একটি (ওয়াচ বা তাত্ক্ষণিক উইন্ডোজ) ব্যবহার করতে হবে str2

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

একবার যেখানে ব্যতিক্রম নিক্ষেপটি স্থাপন করা হয়েছে, নাল মানটি কোথায় [সঠিকভাবে] প্রবর্তিত হয়েছিল তা খুঁজে বের করার জন্য এটি সাধারণত পিছনের দিকে তর্ক করা তুচ্ছ -

ব্যতিক্রমটির কারণটি বুঝতে প্রয়োজনীয় সময় নিন Take নাল অভিব্যক্তি জন্য পরিদর্শন করুন। পূর্বের এক্সপ্রেশনগুলি পরিদর্শন করুন যা এর ফলে নালাগুলি প্রকাশ করতে পারে। যোগ ব্রেকপয়েন্ট যথাযথ হিসাবে প্রোগ্রামের মাধ্যমে এবং ধাপে। ডিবাগারটি ব্যবহার করুন।


1 যদি ব্রেক অন থ্রো খুব আক্রমণাত্মক হয় এবং ডিবাগারটি নেট বা তৃতীয় পক্ষের লাইব্রেরিতে একটি এনপিইতে থামায়, ব্রেক আপ ইউজার-আনহ্যান্ডলড ধরা ব্যতিক্রমগুলি সীমাবদ্ধ করতে ব্যবহার করা যেতে পারে। অতিরিক্তভাবে, ভিএস ২০১২ জাস্ট মাই কোডটি প্রবর্তন করে যা আমি পাশাপাশি সক্ষম করার প্রস্তাব দিই।

আপনি যদি জাস্ট মাই কোডটি সক্ষম করে ডিবাগ করছেন তবে আচরণটি কিছুটা আলাদা। জাস্ট মাই কোডটি সক্ষম করে, ডিবাগার প্রথমবারের সাধারণ ভাষার রানটাইম (সিএলআর) ব্যতিক্রমগুলি উপেক্ষা করে যা আমার কোডের বাইরে ফেলে দেওয়া হয় এবং আমার কোডের মধ্য দিয়ে যায় না


59

সাইমন মুরিয়ার এই উদাহরণ দিয়েছেন :

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

যেখানে একটি আনবক্সিং রূপান্তর (ঢালাই) থেকে 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

সত্তা ফ্রেমওয়ার্কে সত্তার জন্য শ্রেণীর নামটি ওয়েব ফর্ম কোড-পেছনের ফাইলের শ্রেণীর নাম হিসাবে সমেত যখন কেস যুক্ত করা হয়।

ধরুন আপনার একটি ওয়েব ফর্ম কন্টাক্ট.এএসপিএক্স রয়েছে যার কোডবিহীন ক্লাসটি যোগাযোগ এবং আপনার সত্তার নাম পরিচিতি রয়েছে।

তারপরে নীচের কোডটি আপনি প্রসঙ্গটি কল করার সময় একটি নালরফেরান এক্সেক্সশন নিক্ষেপ করবে aveসেচ চেঞ্জস ()

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

সম্পূর্ণতার জন্য ডেটা কনটেক্সট ক্লাস

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

এবং যোগাযোগ সত্তা শ্রেণি। কখনও কখনও সত্তা শ্রেণিগুলি আংশিক ক্লাস হয় যাতে আপনি এগুলি অন্য ফাইলগুলিতেও প্রসারিত করতে পারেন।

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

ত্রুটি দেখা দেয় যখন সত্তা এবং কোডবিহীন বর্গ উভয়ই একই নামের জায়গায় থাকে। এটি ঠিক করার জন্য, পরিচিতি.এএসপিএক্সের জন্য সত্তা শ্রেণি বা কোডবিহীন শ্রেণীর নামকরণ করুন।

কারণ আমি এখনও কারণ সম্পর্কে নিশ্চিত নই। কিন্তু যখনই সত্তা শ্রেণীর যে কোনও একটি সিস্টেমকে প্রসারিত করবে e ওয়েবে.ইউআই.প্যাজে এই ত্রুটি ঘটে।

আলোচনার জন্য DbContext.saveChanges () -তে নাল রেফারেন্সএক্সেপশন দেখুন


41

অন্য একটি সাধারণ ক্ষেত্রে যেখানে কেউ এই ব্যতিক্রমটি পেতে পারে তাতে ইউনিট পরীক্ষার সময় মশকরা ক্লাস জড়িত। বিদ্রূপের কাঠামোটি নির্বিশেষে, আপনার অবশ্যই শ্রেণি শ্রেণিবিন্যাসের সমস্ত উপযুক্ত স্তর যথাযথভাবে উপহাস করা উচিত তা নিশ্চিত করতে হবে। বিশেষত, HttpContextপরীক্ষার অধীনে কোড দ্বারা রেফারেন্সযুক্ত সমস্ত বৈশিষ্ট্যকে অবশ্যই উপহাস করা উচিত।

দেখুন " NullReferenceException নিক্ষিপ্ত কাস্টম AuthorizationAttribute পরীক্ষা যখন " একটি কিছুটা বাগাড়ম্বরপূর্ণ উদাহরণস্বরূপ।


40

এর উত্তর দেওয়ার ক্ষেত্রে আমার আলাদা দৃষ্টিভঙ্গি রয়েছে। এই ধরণের উত্তর "এড়াতে আমি আর কী করতে পারি? "

বিভিন্ন স্তর জুড়ে কাজ করার সময় , উদাহরণস্বরূপ, এমভিসি অ্যাপ্লিকেশনটিতে, একজন নিয়ামককে ব্যবসায়ের ক্রিয়াকলাপগুলি কল করার জন্য পরিষেবাগুলির প্রয়োজন হয়। এই ধরনের পরিস্থিতিতে ডিপেন্ডেন্সি ইনজেকশন কনটেইনারটি নালরফেরানএক্সেপশন এড়ানোর জন্য পরিষেবাগুলি আরম্ভ করার জন্য ব্যবহার করা যেতে পারে । সুতরাং এর অর্থ হল যে আপনাকে নাল পরীক্ষা করার বিষয়ে চিন্তা করার দরকার নেই এবং কেবল নিয়ন্ত্রকের কাছ থেকে পরিষেবাগুলি কল করতে হবে যেমন তারা সর্বদা সিঙ্গলটন বা প্রোটোটাইপ হিসাবে উপলব্ধ (এবং আরম্ভ করা) থাকবে।

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: এটি কেবল একটি একক দৃশ্যের পরিচালনা করে - অবিচ্ছিন্ন নির্ভরতা। এটি নুলারফেরান এক্সেপশনের জন্য একটি সংখ্যালঘু দৃশ্য। বেশিরভাগ ক্ষেত্রে বস্তুগুলি কীভাবে কাজ করে সে সম্পর্কে সাধারণ ভুল বোঝাবুঝি। এরপরে সর্বাধিক ঘন ঘন অন্যান্য পরিস্থিতি যেখানে বিকাশকারীরা ধরে নিয়েছিলেন যে অবজেক্টটি স্বয়ংক্রিয়ভাবে আরম্ভ হবে।
জন স্যান্ডার্স 0

নির্ভরতা ইনজেকশনটি নুলারফেরান এক্সসেপশন এড়াতে সাধারণত ব্যবহৃত হয় না। আমি বিশ্বাস করি না যে আপনি এখানে একটি সাধারণ দৃশ্য পেয়েছেন। যাইহোক , আপনি যদি নিজের উত্তরটিকে স্ট্যাকওভারফ্লো.com/a/15232518 / 76337 এর স্টাইলে আরও বেশি করে সম্পাদনা করেন তবে আমি ডাউনটাওটটি সরিয়ে ফেলব।
জন স্যান্ডার্স

38

"এটি সম্পর্কে আমার কী করা উচিত" বিষয় সম্পর্কে অনেক উত্তর থাকতে পারে।

আপনার কোডটিতে চুক্তি করে ডিজাইন প্রয়োগ করার সময় বিকাশের সময় এ জাতীয় ত্রুটি পরিস্থিতি রোধ করার আরও একটি "আনুষ্ঠানিক" উপায় । এর অর্থ বিকাশকালে আপনার সিস্টেমে শ্রেণি আক্রমণকারী এবং / অথবা এমনকি ফাংশন / পদ্ধতি পূর্বশর্ত এবং পোস্টকন্ডিশনগুলি সেট করা দরকার ।

সংক্ষেপে, শ্রেণি আক্রমণকারীরা নিশ্চিত করে যে আপনার শ্রেণিতে এমন কিছু প্রতিবন্ধকতা থাকবে যা সাধারণ ব্যবহারে লঙ্ঘিত হবে না (এবং সুতরাং, শ্রেণিটি একটি অসামঞ্জস্যপূর্ণ অবস্থাতে পাবেন না )। পূর্ব শর্তগুলির অর্থ হ'ল কোনও ফাংশন / পদ্ধতির ইনপুট হিসাবে প্রদত্ত ডেটা অবশ্যই কিছু বাধা নির্ধারণ করে এবং সেগুলি কখনও লঙ্ঘন করে না এবং পোস্টকন্ডিশনের অর্থ কোনও ফাংশন / পদ্ধতির আউটপুট অবশ্যই সেগুলি কখনও লঙ্ঘন না করে সেট সীমাবদ্ধতা অনুসরণ করবে। চুক্তি অবস্থার উচিত না একটি বাগ মুক্ত প্রোগ্রাম চালানোর সময় লঙ্ঘন করা, অতএব চুক্তি দ্বারা ডিজাইন, ডিবাগ মোডে বাস্তবে পরীক্ষা করা হয় যখন হচ্ছে রিলিজ অক্ষম উন্নত সিস্টেমের কর্মক্ষমতা বাড়ানোর জন্য।

এইভাবে, আপনি 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 অ্যাপ্লিকেশনগুলির জন্য কোড চুক্তি প্রকল্প বিদ্যমান।

অন্যথা, চুক্তি দ্বারা নকশা ব্যবহার প্রয়োগ করা যেতে পারে গবেষকেরা

আপডেট: এটি উল্লেখযোগ্য যে এই শব্দটি বার্ট্র্যান্ড মায়ার তার আইফেল প্রোগ্রামিং ভাষার নকশার সাথে সংযুক্ত করে তৈরি করেছিলেন


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()এটির কল করার কোনও উদ্দেশ্য রয়েছে , তাই সেখানে কোনও নাল রেফারেন্স ব্যতিক্রম ছুঁড়ে ফেলা বুদ্ধিমান হবে না।
Kjartan

31

টিএল; ডিআর: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

ডিবাগিং হ'ল মডেলটি মায়োথরভিউয়ের অভ্যন্তরে নাল ছিল। যতক্ষণ না আমি এটিকে পরিবর্তন করি:

@{
    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
জন স্যান্ডার্স

এছাড়াও, দয়া করে কোন লাইনটি বাদ দিয়েছিল এবং কেন তা দেখান।
জন স্যান্ডার্স

ত্রুটিটি মায়োথরভিউ.সি.এইচটিএমএলে ঘটেছিল, যা আমি এখানে অন্তর্ভুক্ত করি নি, কারণ মডেলটি সঠিকভাবে প্রেরণ করা হয়নি (এটি ছিল Null), তাই আমি জানি যে আমি কীভাবে মডেলটি পাঠাচ্ছিলাম তাতে ত্রুটি ছিল
ট্র্যাভিস হিটার

22

এ ব্যাপারে আপনি কি করতে পারেন?

নাল রেফারেন্স কী এবং কীভাবে এটি ডিবাগ করা যায় তা ব্যাখ্যা করে এখানে অনেক ভাল উত্তর রয়েছে। তবে কীভাবে সমস্যাটি রোধ করা যায় বা কমপক্ষে এটি সহজে ধরা সহজতর করা যায় very

যুক্তি যাচাই করুন

উদাহরণস্বরূপ, পদ্ধতিগুলি নাল এবং নিক্ষিপ্ত হয় কিনা তা দেখতে বিভিন্ন আর্গুমেন্টগুলি পরীক্ষা করতে পারে ArgumentNullException, স্পষ্টতই এই সঠিক উদ্দেশ্যে তৈরি একটি ব্যতিক্রম।

ArgumentNullExceptionএমনকি নির্মাণের জন্য প্যারামিটারটির নাম এবং একটি বার্তা যুক্তি হিসাবে গ্রহণ করে যাতে আপনি বিকাশকারীকে সমস্যাটি ঠিক কী তা বলতে পারেন।

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

সরঞ্জাম ব্যবহার করুন

এছাড়াও সাহায্য করতে পারে এমন বেশ কয়েকটি গ্রন্থাগার রয়েছে। উদাহরণস্বরূপ "পুনরায় ভাগ করুন" আপনি কোড লেখার সময় আপনাকে সতর্কবার্তা সরবরাহ করতে পারে, বিশেষত যদি আপনি তাদের বৈশিষ্ট্যটি ব্যবহার করেন: নটঅ্যাট্রিবিউট

"মাইক্রোসফ্ট কোড চুক্তিগুলি" রয়েছে যেখানে আপনি সিনট্যাক্স ব্যবহার করেন Contract.Requires(obj != null)যা আপনাকে রানটাইম এবং সংকলন পরীক্ষা করে দেয়: কোড চুক্তিগুলি উপস্থাপন করছে

এখানে "পোস্টশার্প" রয়েছে যা আপনাকে কেবল এই জাতীয় বৈশিষ্ট্য ব্যবহার করতে দেয়:

public void DoSometing([NotNull] obj)

এটি করে এবং আপনার বিল্ড প্রক্রিয়াটির পোস্টশার্প অংশ তৈরি করে objরানটাইমের সময় নাল জন্য পরীক্ষা করা হবে। দেখুন: পোস্টশার্প নাল চেক

সরল কোড সমাধান

অথবা আপনি সর্বদা সরল পুরানো কোড ব্যবহার করে আপনার নিজস্ব পদ্ধতির কোড করতে পারেন। উদাহরণস্বরূপ এখানে একটি স্ট্রাক্ট যা আপনি নাল রেফারেন্সগুলি ধরতে ব্যবহার করতে পারেন। এটি একই ধারণা অনুসারে মডেল করা হয়েছে 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সম্পত্তির মাধ্যমে অন্তর্নিহিত মানটি অ্যাক্সেস করতে পারবেন । বিকল্পভাবে, আপনি একটি সুস্পষ্ট বা অন্তর্নিহিত castালাই ব্যবহার করতে পারেন, আপনি নীচের রিটার্ন মান সহ একটি উদাহরণ দেখতে পারেন:

Person person = GetPerson();

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

অথবা আপনি এমনকি এটি ব্যবহার করতে পারেন যখন পদ্ধতিটি কেবল cast ালাই করে ফিরে আসে 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

আপনার রেফারেন্সের জন্য আমি গিটহাবের উপরের কোডটি উপলভ্য করেছি, আপনি এটি এখানে পেতে পারেন:

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ঠিকানা isnull`।

এটি দুর্দান্ত বৈশিষ্ট্য, তবে এটি আপনাকে কম তথ্য দেয়। এটি 4 টির মধ্যে কোনটি নাল তা স্পষ্ট করে না।

অন্তর্নির্মিত নল এর মতো?

সি # এর জন্য একটি দুর্দান্ত শর্টহ্যান্ড রয়েছে Nullable<T>, আপনি এ জাতীয় ধরণের পরে একটি প্রশ্ন চিহ্ন রেখে কিছু নমনীয় করতে পারেন int?

এটা তোলে চমৎকার হবে যদি C # এর ভালো কিছু ছিল NotNull<T>উপরে struct হয় এবং একটি অনুরূপ সাধারণভাবে সংক্ষেপে, হয়তো বিস্ময়বোধক বিন্দু ছিল যাতে আপনি ভালো কিছু লিখতে পারে যে (!): public void WriteName(Person! person)


2
কখনই নালরফেরানএক্সেপশন
জন জন স্যান্ডার্স

@ জনসন্ডার্স সাহস আমি জিজ্ঞাসা করি কেন? (সিরিয়াসলি যদিও কেন?)
লুইস পেরেজ

2
নুলারফেরেন্সএক্সেপশন বলতে সিএলআর দ্বারা ছোঁড়া বোঝানো হয়েছে। এর অর্থ হ'ল কোনও নাল সম্পর্কে একটি রেফারেন্স এসেছে। এর অর্থ এই নয় যে কোনও নাল সম্পর্কে একটি রেফারেন্স ঘটবে কেবল আপনি চতুরতার সাথে প্রথমে পরীক্ষা করে।
জন স্যান্ডার্স

আমি কীভাবে বিভ্রান্তিকর হবে সে সম্পর্কে আপনার বক্তব্যটি দেখছি। আমি এই উদাহরণটির জন্য একটি নিয়মিত ব্যতিক্রম এবং গিটহাবের একটি কাস্টম ব্যতিক্রম আপডেট করেছি।
লুইস পেরেজ

যেমন একটি প্রাথমিক প্রশ্নের দুর্দান্ত উত্তর। আপনার কোডটি ব্যর্থ হলে এটি খুব খারাপ হয় না। আপনি যখন নির্ভর করছেন এমন কোনও বাণিজ্যিক তৃতীয় পক্ষের লাইব্রেরির গভীর থেকে যখন এটি আসে তখন এটি ভয়াবহ হয় এবং গ্রাহক সমর্থন এটি আপনার কোড যা সমস্যা তৈরি করছে তা হতে হবে বলে জোর দিয়ে চলে। এবং আপনার সম্পূর্ণরূপে নিশ্চিত নয় যে এটি নেই এবং পুরো প্রকল্পটি বন্ধ হয়ে যেতে পারে .. আমি আসলে মনে করি এটি আমার সমাধিস্থলটির জন্য একটি উপযুক্ত প্রতিবেদন তৈরি করতে পারে: "অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণ হিসাবে সেট করা হয়নি not"
ড্যারেল লি

10

মজার বিষয় হচ্ছে, এই পৃষ্ঠার কোনও উত্তর দুটি প্রান্তের মামলার উল্লেখ করে না, আশা করি আমি যদি এগুলি যুক্ত করি তবে কারও মনেই আসেনি:

এজ কেস # 1: অভিধানে একযোগে অ্যাক্সেস

.NET এর জেনেরিক অভিধানগুলি থ্রেড-নিরাপদ নয় এবং তারা কখনও কখনও একটি NullReferenceবা এমনকি আরও ঘন ঘন নিক্ষেপ করতে পারেKeyNotFoundException আপনি যখন দুটি সমবর্তী থ্রেড থেকে কোনও কী অ্যাক্সেস করার চেষ্টা করেন । ব্যতিক্রমটি এক্ষেত্রে বেশ বিভ্রান্তিকর।

এজ কেস # 2: অনিরাপদ কোড

যদি কোনও কোড NullReferenceExceptionদ্বারা নিক্ষেপ করা হয় তবে unsafeআপনি আপনার পয়েন্টার ভেরিয়েবলগুলি দেখে এবং সেগুলি পরীক্ষা করতে পারেনIntPtr.Zero বা অন্য করতে পারেন। যা একই জিনিস ("নাল পয়েন্টার ব্যতিক্রম"), তবে অনিরাপদ কোডে ভেরিয়েবলগুলি প্রায়শই মান-ধরণের / অ্যারে ইত্যাদিতে নিক্ষেপ করা হয় এবং আপনি কোনও ভ্যালু-টাইপ কীভাবে এটি নিক্ষেপ করতে পারেন তা অবাক করে ভেবে অবাক করে দেন against ব্যতিক্রম।

(যদি আপনার প্রয়োজন না হয় তবে অনিরাপদ কোডটি ব্যবহার না করার আরও একটি কারণ)


5
আপনার অভিধানের উদাহরণটি কোনও প্রান্তের মামলা নয়। যদি অবজেক্টটি থ্রেড নিরাপদে না থাকে, তবে একাধিক থ্রেড থেকে এটি ব্যবহার করা এলোমেলো ফলাফল দেয়। আপনার অনিরাপদ কোড উদাহরণটি nullকোন উপায়ে আলাদা ?
জন স্যান্ডার্স

10

আপনি নাল-কন্ডিশনাল অপারেটরগুলি সি # 6 এ ব্যবহার করে একটি পরিষ্কার উপায়ে নুলারফেরেন্সএক্সেপশন ঠিক করতে পারেন এবং নাল চেকগুলি পরিচালনা করতে কম কোড লিখতে পারেন।

সদস্য অ্যাক্সেস (?।) বা সূচক (? [) ক্রিয়াকলাপ সম্পাদনের আগে নাল পরীক্ষা করার জন্য এটি ব্যবহার করা হয়।

উদাহরণ

  var name = p?.Spouse?.FirstName;

সমান:

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

ফলাফলটি হ'ল পি নাল হয়ে গেলে বা পি.স্পেস নাল হলে নামটি নাল হবে।

অন্যথায়, চলক নামটি p.Spouse.FirstName এর জন্য নির্ধারিত হবে।

আরও বিশদের জন্য: নাল-কন্ডিশনাল অপারেটর


9

ত্রুটি লাইন "অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণ হিসাবে সেট করা হয়নি।" সূচিত করে যে আপনি কোনও অবজেক্ট রেফারেন্সের জন্য ইনস্ট্যান্স অবজেক্ট বরাদ্দ করেননি এবং এখনও আপনি সেই বস্তুর যথাযথতা / পদ্ধতিগুলি অ্যাক্সেস করছেন।

উদাহরণস্বরূপ: ধরা যাক আপনার কাছে মাই ক্লাস নামে একটি শ্রেণি রয়েছে এবং এতে একটি সম্পত্তি প্রোপ 1 রয়েছে।

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
     }
}

উপরের রেখায় ত্রুটি ছুঁড়েছে কারণ ক্লাস মাই ক্লাসের রেফারেন্স ঘোষণা করা হলেও তা তাত্ক্ষণিকভাবে নয় বা অবজেক্টের কোনও উদাহরণ সেই শ্রেণীর রেফার্কনে বরাদ্দ করা হয়নি।

এটি ঠিক করার জন্য আপনাকে তাত্ক্ষণিকভাবে চালিত করতে হবে (সেই শ্রেণীর রেফারেন্সের জন্য অবজেক্টটি নির্ধারণ করুন)।

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

4

আপনি যে শ্রেণীরটি ব্যবহার করার চেষ্টা করছেন তার কোনও বস্তু তাত্ক্ষণিকভাবে চালু না হলে নলের রেফারেন্সএক্সেপশন বা অবজেক্ট রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয় না occurs উদাহরণ স্বরূপ:

ধরুন আপনার কাছে স্টুডেন্ট নামের একটি ক্লাস রয়েছে।

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 - স্টেটমেন্টটি কেবল স্টুডেন্ট স্টুডেন্টের ভেরিয়েবল ঘোষণা করে, লক্ষ্য রাখবেন যে স্টুডেন্ট ক্লাসটি এই মুহুর্তে ইনস্ট্যান্ট হয় না। অতএব, যখন s.GetFullName () বিবৃতিটি কার্যকর হবে, তখন এটি নালরফেরান এক্সেক্সশনটি নিক্ষেপ করবে।


3

ভাল, সহজ ভাষায়:

আপনি এমন কোনও বস্তু অ্যাক্সেস করার চেষ্টা করছেন যা বর্তমানে তৈরি হয়নি বা মেমরিতে নেই।

সুতরাং কিভাবে এটি মোকাবেলা:

  1. ডিবাগ করুন এবং ডিবাগারটি বিরতি দিন ... এটি আপনাকে ভাঙা ভেরিয়েবলটিতে সরাসরি নিয়ে যাবে ... এখন আপনার কাজটি কেবল এটি ঠিক করা ঠিক আছে ... উপযুক্ত জায়গায় নতুন কীওয়ার্ডটি ব্যবহার করে ।

  2. যদি এটি কিছু ডাটাবেস কমান্ডের কারণে ঘটে থাকে কারণ বস্তুটি উপস্থিত না থাকে তবে আপনাকে যা করতে হবে তা হল একটি নাল চেক করা এবং এটি পরিচালনা করা:

    if (i == null) {
        // Handle this
    }
  3. সবচেয়ে শক্ত একটি .. যদি জিসি ইতিমধ্যে বস্তুটি সংগ্রহ করে ... সাধারণত আপনি যদি স্ট্রিং ব্যবহার করে কোনও বিষয় সন্ধান করার চেষ্টা করছেন এটি ঘটে ... এটি হ'ল বস্তুর নাম অনুসারে এটি সন্ধান করতে পারে তবে জিসি ইতিমধ্যে হতে পারে এটি পরিষ্কার করে দেওয়া ... এটি খুঁজে পাওয়া শক্ত এবং বেশ সমস্যা হয়ে উঠবে ... এটি মোকাবেলার জন্য আরও ভাল উপায় বিকাশ প্রক্রিয়া চলাকালীন যেখানে প্রয়োজন সেখানে নাল চেক করা। এটি আপনার অনেক সময় সাশ্রয় করবে।

নাম অনুসারে সন্ধান করার অর্থ আমার অর্থ কিছু ফ্রেমওয়ার্ক আপনাকে স্ট্রিং এবং কোড ব্যবহার করে FIndObજેક્ટগুলিতে অনুমতি দেয়: FindObject ("অবজেক্টনাম");


3
আপনার যদি কোনও জিনিসের বিষয়ে উল্লেখ থাকে, তবে জিসি এটিকে কখনই পরিষ্কার করে না
জন স্যান্ডার্স

2
যদি আপনি ফাইন্ডবজেক্ট ("অবজেক্টের নাম") এর মতো জিনিস ব্যবহার করেন তবে জিসি হাতের আগে জানতে পারবে না যে আপনি সেই অবজেক্টটি রেফেন্স করতে চলেছেন .. এটিই ব্যাখ্যা করার চেষ্টা করছিল .. এগুলি রানটাইমের সময় ঘটে
আকাশ গুথা

2
কিছু ফ্রেমওয়ার্ক রয়েছে যা ইউনি # এর মতো সি # তে এই কার্যকারিতা সরবরাহ করে। প্রশ্নটির সাথে বিসিএল সম্পর্কিত কিছু নেই। সমালোচনা করার আগে ইন্টারনেটে অনুসন্ধান করুন তাদের মতো অনেকগুলি ফাংশন রয়েছে এবং আপনার সদয় তথ্যের জন্য আমি এটি প্রতিদিন ব্যবহার করি। এখন দয়া করে বলুন কীভাবে উত্তরটি কোনওরকম করে না।
আকাশ গুঠা

2
ডকস.িউনিটি 3 ডি / স্ক্রিপ্ট রেফারেন্স /… লিঙ্কটি চেক করুন এবং নিজেকে মিঃ এক্স্পার্ট: পি
আকাশ গুঠা

আপনার লিঙ্কটিতে আমি যে উদাহরণগুলি দেখেছি সেগুলি গেমওজেক্টের ফলাফল নির্ধারণ করে a একটি সদস্য ক্ষেত্রে সন্ধান করুন। এটি একটি রেফারেন্স এবং জিসি এটি অবধি সংগ্রহ করবে না যতক্ষণ না ধারণকারী বস্তুটি সংগ্রহ করা হয়।
জন স্যান্ডার্স

1

আক্ষরিক অর্থে নুলারফেরান এক্সেপশনটি ঠিক করার সবচেয়ে সহজ উপায় দুটি উপায়। আপনার যদি গেমস অবজেক্ট উদাহরণস্বরূপ স্ক্রিপ্ট সংযুক্ত থাকে এবং একটি আরবি নামক ভেরিয়েবল (rigidbody) থাকে তবে আপনি যখন আপনার খেলা শুরু করবেন তখন এই পরিবর্তনশীলটি শূন্য হয়ে যাবে।
এই কারণেই আপনি একটি নালরফেরানএক্সেপশন পান কারণ কম্পিউটারে সেই পরিবর্তনশীলটিতে ডেটা সংরক্ষণ করা হয় না।

আমি উদাহরণ হিসাবে একটি রিগিডবডি ভেরিয়েবল ব্যবহার করব।
আমরা আসলে কয়েকটি উপায়ে সহজেই ডেটা যুক্ত করতে পারি:

  1. অ্যাড কমম্পোনেন্ট> ফিজিক্স> রিগিডোডি সহ আপনার অবজেক্টে একটি রিগিডবডি যুক্ত করুন
    তারপরে আপনার স্ক্রিপ্টে যান এবং টাইপ করুন কোডটির rb = GetComponent<Rigidbody>();
    এই লাইনটি আপনার Start()বা Awake()ফাংশনের অধীনে সবচেয়ে ভাল কাজ করে।
  2. আপনি প্রোগ্রামগতভাবে একটি উপাদান যুক্ত করতে এবং কোডের এক লাইনের সাথে একই সময়ে ভেরিয়েবলটি নির্ধারণ করতে পারেন: rb = AddComponent<RigidBody>();

আরও নোট: আপনি যদি object [RequireComponent(typeof(RigidBody))]ক্যটি আপনার সামগ্রীতে কোনও উপাদান যুক্ত করতে চান এবং আপনি একটি যুক্ত করতে ভুলে যেতে পারেন তবে আপনি আপনার শ্রেণীর ঘোষণার উপরে (আপনার সমস্ত ব্যবহারের নীচে স্থান) টাইপ করতে পারেন ।
গেমস উপভোগ করুন এবং মজা করুন!


-1

যদি আমরা সাধারণ পরিস্থিতি বিবেচনা করি যেখানে এই ব্যতিক্রমটি ছুঁড়ে ফেলা যায়, শীর্ষে উইনিং অবজেক্টগুলিতে অ্যাক্সেস করা।

উদা:

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

এখানে, যদি ঠিকানাটি শূন্য হয়, তবে আপনি নালরফেরান এক্সেপশন পাবেন।

সুতরাং, অনুশীলন হিসাবে আমাদের সর্বদা নাল চেক ব্যবহার করা উচিত, এই জাতীয় বস্তুগুলিতে বৈশিষ্ট্য অ্যাক্সেস করার আগে (বিশেষত জেনেরিক)

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

-3

এটি মূলত একটি নাল রেফারেন্স ব্যতিক্রমমাইক্রোসফ্ট যেমন বলেছে-

আপনি কোনও ধরণের সদস্যের অ্যাক্সেস করার চেষ্টা করার সময় একটি নালরফেরানএক্সেপশন ব্যতিক্রম ছুঁড়ে দেওয়া হয় যার মূল্য নাল।

ওটার মানে কি?

এর অর্থ যদি কোনও সদস্যের কোনও মূল্য থাকে না এবং আমরা সেই সদস্যকে নির্দিষ্ট কাজ সম্পাদনের জন্য তৈরি করে দিই তবে সিস্টেম নিঃসন্দেহে একটি বার্তা টস করবে এবং বলে-

"আরে অপেক্ষা করুন, সেই সদস্যের কোনও মূল্য নেই তাই এটি যে কাজটি আপনি এটি অর্পণ করছেন তা সম্পাদন করতে পারে না।"

ব্যতিক্রম নিজেই বলে যে কিছু উল্লেখ করা হচ্ছে তবে যার মান সেট করা হচ্ছে না। সুতরাং এটি নির্দেশ করে যে এটি কেবলমাত্র রেফারেন্স প্রকারগুলি ব্যবহার করার সময় ঘটে যখন মান প্রকারগুলি অ-অযোগ্য।

আমরা যদি ভ্যালু টাইপের সদস্য ব্যবহার করি তবে নালরফেরানএক্সেপশনটি ঘটবে না।

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

উপরের কোডটি সরল স্ট্রিং দেখায় যা নাল দ্বারা নির্ধারিত মান ।

এখন, যখন আমি স্ট্রিং এর দৈর্ঘ্য প্রিন্ট করতে চেষ্টা Str পেতে আমি কি টাইপ 'System.NullReferenceException' একটি Unhandled ব্যতিক্রম ঘটেছে কারণ বার্তা সদস্য Str নাল প্রতি নির্দেশ করা হয় এবং সেখানে নাল এর যে কোন দৈর্ঘ্যের হতে পারে না।

' নালরফেরেন্সএক্সেপশনআমরা যখন কোনও রেফারেন্স টাইপ ইনস্ট্যান্ট করতে ভুলে যাই তখনও ' হয়।

ধরুন এতে আমার ক্লাস এবং সদস্য পদ্ধতি রয়েছে। আমি আমার ক্লাস ইনস্ট্যান্টেশন করি নি তবে কেবল আমার ক্লাসের নাম রেখেছি। এখন আমি যদি পদ্ধতিটি ব্যবহার করার চেষ্টা করি তবে সংকলকটি একটি ত্রুটি ফেলবে বা একটি সতর্কতা জারি করবে (সংকলকের উপর নির্ভর করে)।

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");

    }
}

উপরের কোডটির জন্য সংকলক একটি ত্রুটি উত্থাপন করে যা ভেরিয়েবল অজেক্টকে নিযুক্ত করা হয় যা আমাদের ভেরিয়েবলের নাল মান বা কিছুই নেই তা বোঝায়। উপরের কোডটির জন্য সংকলক একটি ত্রুটি উত্থাপন করে যা ভেরিয়েবল অজেক্টকে নিযুক্ত করা হয় যা আমাদের ভেরিয়েবলের নাল মান বা কিছুই নেই তা বোঝায়।

কেন হয়?

  • বস্তুর মান পরীক্ষা না করার জন্য আমাদের ত্রুটির কারণে নুলরেফারেন্সএক্সেপশন উত্থিত হয়। আমরা প্রায়শই কোড বিকাশে অবজেক্টের মানগুলি চেক না করে রেখে দেই।

  • যখন আমরা আমাদের অবজেক্টগুলি ইনস্ট্যান্ট করতে ভুলে যাই তখনও এটি উত্থাপিত হয়। পদ্ধতি, বৈশিষ্ট্য, সংগ্রহ ইত্যাদি ব্যবহার করা যা নাল মানগুলি ফিরিয়ে দিতে বা সেট করতে পারে তাও এই ব্যতিক্রমের কারণ হতে পারে।

কীভাবে এড়ানো যায়?

এই নামী ব্যতিক্রম এড়ানোর জন্য বিভিন্ন উপায় এবং পদ্ধতি রয়েছে:

  1. সুস্পষ্ট চেকিং: বস্তু, বৈশিষ্ট্য, পদ্ধতি, অ্যারে এবং সংগ্রহগুলি নাল কিনা তা আমাদের চেক করার traditionতিহ্যটি মেনে চলতে হবে। এটি কেবল শর্তাধীন বিবৃতি যেমন যদি-অন্যথায় অন্যথায় ইত্যাদি ব্যবহার করে প্রয়োগ করা যেতে পারে etc.

  2. ব্যতিক্রম হ্যান্ডলিং: এই ব্যতিক্রম পরিচালনার অন্যতম গুরুত্বপূর্ণ উপায়। সাধারণ চেষ্টা-অবশেষে অবরুদ্ধ ব্লকগুলি ব্যবহার করে আমরা এই ব্যতিক্রমটি নিয়ন্ত্রণ করতে পারি এবং এটির লগও বজায় রাখতে পারি। আপনার অ্যাপ্লিকেশন উত্পাদন পর্যায়ে থাকলে এটি খুব কার্যকর হতে পারে।

  3. নাল অপারেটর: নাল কোলেসিং অপারেটর এবং নাল কন্ডিশনাল অপারেটরগুলি অবজেক্টস, ভেরিয়েবল, বৈশিষ্ট্য এবং ক্ষেত্রগুলিতে মান নির্ধারণের ক্ষেত্রেও ব্যবহৃত হতে পারে।

  4. ডিবাগার: বিকাশকারীদের জন্য, আমাদের সাথে ডিবাগিংয়ের বড় অস্ত্র রয়েছে। বিকাশের সময় যদি আমরা নালরফেরেন্সএক্সেপশনের মুখোমুখি হয়ে থাকি তবে আমরা ব্যতিক্রমের উত্সে পেতে ডিবাগারটি ব্যবহার করতে পারি।

  5. অন্তর্নির্মিত পদ্ধতি: সিস্টেম পদ্ধতি যেমন গেটভ্যালিঅরডেফল্ট (), ইসনুলআরওহাইটস্পেস () এবং ইসনুলারএম্প্টি () নালগুলির জন্য পরীক্ষা করে এবং যদি কোনও নাল মান থাকে তবে ডিফল্ট মান নির্ধারণ করে।

ইতিমধ্যে এখানে অনেক ভাল উত্তর রয়েছে। আপনি আমার ব্লগে উদাহরণ সহ আরও বিশদ বিবরণ পরীক্ষা করতে পারেন ।

আশা করি এটিও সাহায্য করবে!


আপনি মূলত সেই ব্লগ পোস্টের অর্ধেক অনুলিপি করেছেন এবং এমন নতুন কিছুই যুক্ত করেননি যা বিদ্যমান উত্তরগুলি সম্বোধন করে না।
কোডকাস্টার

@ কোডেকাস্টার যখন আপনি নিজের ব্লগ থেকে কোনও সংক্ষিপ্ত বিবরণ লিখেন তখন কি এটি অনুলিপি করা হয়? আমি জানি আমার উত্তরে নতুন কিছু নেই এবং পূর্বের উত্তরগুলির কাছে নতুন কিছু নেই তবে আমি আরও পরিশীলিত উপায়ে অবদান রাখতে এবং অন্যকে যেভাবে বুঝলাম তা বুঝতে দিতে চাই। এটি একক ব্যক্তিকে সহায়তা করলেও খুশি হবে। সরল বিশ্বাসে.
ওয়াসিম

-4

বিল্ডটি সংরক্ষণ বা সংকলনের সময় যদি কেউ এই বার্তাটি পেয়ে থাকেন তবে কেবলমাত্র সমস্ত ফাইল বন্ধ করুন এবং তারপরে যেকোন ফাইল সংকলন এবং সংরক্ষণের জন্য খুলুন।

আমার জন্য কারণটি ছিল যে আমি ফাইলটির নতুন নামকরণ করেছি এবং পুরানো ফাইলটি এখনও খোলা ছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.