আমার কিছু কোড রয়েছে এবং যখন এটি কার্যকর হয়, এটি একটি নিক্ষেপ করে NullReferenceException
বলে:
অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি।
এর অর্থ কী এবং এই ত্রুটিটি ঠিক করতে আমি কী করতে পারি?
আমার কিছু কোড রয়েছে এবং যখন এটি কার্যকর হয়, এটি একটি নিক্ষেপ করে NullReferenceException
বলে:
অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি।
এর অর্থ কী এবং এই ত্রুটিটি ঠিক করতে আমি কী করতে পারি?
উত্তর:
আপনি এমন কিছু ব্যবহার করার চেষ্টা করছেন যা null
(বা Nothing
ভিবি.এনইটি তে) রয়েছে। এর অর্থ আপনি এটি সেট করেছেন null
বা আপনি এটিকে কখনই সেট করেন না।
অন্য কিছুর মত, null
চারপাশে পাস হয়ে যায়। যদি হয়null
এ পদ্ধতি "একটি", এটা হতে পারে যে পদ্ধতি "বি" একটি পাস null
থেকে পদ্ধতি "একজন"।
null
বিভিন্ন অর্থ হতে পারে:
NullReferenceException
।null
। নোট করুন যে সি # এর ভেরিয়েবলগুলির জন্য নলাবদ্ধ ডেটাটাইপগুলির ধারণা রয়েছে (যেমন ডাটাবেস টেবিলগুলিতে নমনীয় ক্ষেত্র থাকতে পারে) - 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
যদি রেফ 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!";
}
}
// 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>
উপাদানটি প্রদান করে।
চালু C# 8
আছে নাল প্রসঙ্গ এবং nullable রেফারেন্স ধরনের ভেরিয়েবল উপর স্ট্যাটিক বিশ্লেষণ সঞ্চালন এবং যদি একটি মান সম্ভাব্য নাল হতে পারে বা নাল জন্য সেট করা হয়েছে একটি কম্পাইলার সতর্কবার্তা প্রদান করে। নালযোগ্য রেফারেন্স ধরণগুলি প্রকারগুলিকে স্পষ্টভাবে শূন্য করার অনুমতি দেয়।
Nullable
আপনার csproj
ফাইলের এলিমেন্টটি ব্যবহার করে কোনও প্রজেক্টের জন্য অযোগ্য টিকা রচনার প্রসঙ্গ এবং অযোগ্য সতর্কতা প্রসঙ্গে সেট করা যেতে পারে । এই উপাদানটি কনফিগার করে যে কীভাবে সংকলক প্রকারের nlalability ব্যাখ্যা করে এবং কী সতর্কতা উত্পন্ন হয়। বৈধ সেটিংস হ'ল:
নালযোগ্য রেফারেন্স টাইপটি একই সিনট্যাক্স ব্যবহার করে নুলযোগ্য মান ধরণের হিসাবে নোট করা হয়: একটি ?
ভেরিয়েবলের ধরণের সাথে যুক্ত হয়।
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#
নামটি থেকে বোঝা যায় যে একটি "অনিরাপদ" মোড রয়েছে যা অত্যন্ত বিপজ্জনক কারণ মেমরির সুরক্ষা এবং টাইপ সুরক্ষা সরবরাহকারী সাধারণ সুরক্ষা ব্যবস্থা প্রয়োগ করা হয় না। মেমরি কীভাবে কাজ করে তা সম্পর্কে আপনার কাছে গভীর এবং গভীর ধারণা না থাকলে আপনার অনিরাপদ কোডটি লেখা উচিত নয় ।
অনিরাপদ মোডে আপনার দুটি গুরুত্বপূর্ণ তথ্য সম্পর্কে সচেতন হওয়া উচিত:
এটি কেন তা বোঝার জন্য এটি বুঝতে সহায়তা করে যে কীভাবে .NET প্রথমে নাল ডিসেফারেন্স ব্যতিক্রম তৈরি করে। (এই বিবরণগুলি উইন্ডোজ চলমান .NET- এ প্রযোজ্য; অন্যান্য অপারেটিং সিস্টেমগুলি অনুরূপ প্রক্রিয়া ব্যবহার করে))
মেমরি ভার্চুয়ালাইজড হয় Windows
; প্রতিটি প্রক্রিয়া অপারেটিং সিস্টেম দ্বারা ট্র্যাক করা মেমরির অনেক "পৃষ্ঠাগুলির" একটি ভার্চুয়াল মেমরি স্থান পায়। মেমোরির প্রতিটি পৃষ্ঠায় পতাকা লাগানো থাকে যা এটি কীভাবে ব্যবহার করা যেতে পারে তা নির্ধারণ করে: পাঠানো, এতে লিখিত, সম্পাদন করা ইত্যাদি। সর্বনিম্ন পৃষ্ঠা "যদি কখনও কোন ভাবে ব্যবহার করার সময় একটি ত্রুটি উৎপন্ন" হিসেবে চিহ্নিত করা হয়।
একটি নাল পয়েন্টার এবং একটি নাল রেফারেন্স C#
উভয়ই অভ্যন্তরীণভাবে শূন্য সংখ্যা হিসাবে উপস্থাপিত হয়, এবং সুতরাং এটির সাথে সম্পর্কিত মেমরি স্টোরেজটিতে এটিকে মূল্যহ্রাস করার কোনও প্রচেষ্টা অপারেটিং সিস্টেমকে ত্রুটি তৈরি করার কারণ করে। .NET রানটাইম এরপরে এই ত্রুটিটি সনাক্ত করে এবং এটিকে নাল ডিरेফারেন্স ব্যতিক্রমে রূপান্তরিত করে।
একারণে নাল পয়েন্টার এবং নাল রেফারেন্স উভয়কেই সমাহার করা একই ব্যতিক্রম ঘটায়।
দ্বিতীয় দফার কী হবে? ভার্চুয়াল মেমরির সর্বনিম্ন পৃষ্ঠায় আসা যে কোনও অবৈধ পয়েন্টারকে ডিফার করা একই অপারেটিং সিস্টেম ত্রুটির কারণ হয়ে দাঁড়ায় এবং এর ফলে একই ব্যতিক্রম ঘটে।
কেন এটা বোঝা যায়? ঠিক আছে, ধরুন আমাদের দুটি কাঠামো সমন্বিত একটি কাঠামো আছে এবং একটি অব্যবহৃত পয়েন্টার নাল সমান। যদি আমরা স্ট্রাক্টে দ্বিতীয় ইনট্রিকে অবজ্ঞার চেষ্টা করি, তবে CLR
এটি শূন্যের স্থানে স্টোরেজ অ্যাক্সেস করার চেষ্টা করবে না; এটি চারটি স্থানে স্টোরেজ অ্যাক্সেস করবে। কিন্তু কথাটি এই ডি-রেফারেন্স কারণ আমরা ঐ ঠিকানায় পাচ্ছেন একটি নাল মাধ্যমে নাল।
আপনি যদি অনিরাপদ কোড নিয়ে কাজ করছেন এবং আপনি যদি একটি নাল ডিসেফারেন্স ব্যতিক্রম পেয়ে থাকেন তবে কেবল সচেতন হন যে আপত্তিকর পয়েন্টারটি নালার দরকার নেই। এটি সর্বনিম্ন পৃষ্ঠায় যে কোনও অবস্থান হতে পারে এবং এই ব্যতিক্রমটি উত্পাদিত হবে।
new Book { Author = { Age = 45 } };
অভ্যন্তরীণ সূচনাটি কীভাবে এমনকি কীভাবে হয় ... আমি এমন কোনও পরিস্থিতির কথা ভাবতে পারি না যেখানে অভ্যন্তরীণ উদ্যোগ কখনই কাজ করবে, তবু এটি সংকলন এবং বুদ্ধিদীপ্ত কাজ করে ... স্ট্রাক্ট না থাকলে?
NullReference Exception
জন্য ভিসুয়াল বেসিক মধ্যে এক থেকে কোন পার্থক্য নাই সি # । সর্বোপরি, তারা উভয়ই .NET ফ্রেমওয়ার্কে সংজ্ঞায়িত একই ব্যতিক্রমের প্রতিবেদন করছে যা তারা উভয়ই ব্যবহার করে। ভিজ্যুয়াল বেসিকের অনন্য কারণগুলি বিরল (সম্ভবত কেবল একটি)।
এই উত্তরটি ভিজ্যুয়াল বেসিক পদগুলি, বাক্য গঠন এবং প্রসঙ্গ ব্যবহার করবে। ব্যবহৃত উদাহরণগুলি প্রচুর অতীত স্ট্যাক ওভারফ্লো প্রশ্ন থেকে আসে। পোস্টে প্রায়শই দেখা যায় এমন ধরণের পরিস্থিতি ব্যবহার করে প্রাসঙ্গিকতা সর্বাধিককরণের জন্য এটি । যাদের প্রয়োজন হতে পারে তাদের জন্য আরও কিছুটা ব্যাখ্যা প্রদান করা হয়েছে। আপনার অনুরূপ উদাহরণ খুব সম্ভবত এখানে তালিকাভুক্ত করা হয়।
বিঃদ্রঃ:
NullReferenceException
(এনআরই) কী কী কারণে হয়, এটি কীভাবে সন্ধান করা যায়, কীভাবে এটি ঠিক করা যায় এবং কীভাবে এড়ানো যায় তা বুঝতে আপনাকে সহায়তা করার উদ্দেশ্যে এটি করা হয়েছে। একটি এনআরই এর অনেক কারণ হতে পারে তাই এটি আপনার একমাত্র মুখোমুখি হওয়ার সম্ভাবনা নেই।" অবজেক্টটির কোনও উদাহরণে সেট করা হয়নি" বার্তাটির অর্থ আপনি কোনও অবজেক্টটি ব্যবহার করার চেষ্টা করছেন যা আরম্ভ করা হয়নি। এটি এর মধ্যে একটিতে সিদ্ধ হয়:
যেহেতু সমস্যাটি কোনও অবজেক্ট রেফারেন্স যা হ'ল 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
দ্রষ্টব্য: কনস্ট্রাক্টর ( ) সহ কোনও পদ্ধতিতে আবার ব্যবহার করবেন না :Dim
Sub 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
বনাম Employee
। DataTable
"কর্মচারী" নামে কোনও নাম তৈরি করা হয়নি, সুতরাং 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' পরে) হয় .ExecuteReader
। Catch
কিছু না করার পরে , 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
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
(সর্বদা) ব্যবহার করুন ।
অন্য দৃশ্যাবলীটি হ'ল যখন আপনি কোনও মান প্রকারে কোনও নাল বস্তু নিক্ষেপ করেন । উদাহরণস্বরূপ, নীচের কোড:
object o = null;
DateTime d = (DateTime)o;
এটি নিক্ষেপ করবে NullReferenceException
কাস্টের উপরে ফেলে দেবে। উপরের নমুনায় এটি বেশ সুস্পষ্ট বলে মনে হয়, তবে এটি আরও "দেরি-বাঁধাই করা" জটিল পরিস্থিতিগুলিতে ঘটতে পারে যেখানে নাল অবজেক্টটি আপনার নিজের নয় এমন কিছু কোড থেকে ফিরে এসেছে এবং কাস্ট উদাহরণটি কিছু স্বয়ংক্রিয় সিস্টেম দ্বারা উত্পন্ন।
এর একটি উদাহরণ ক্যালেন্ডার নিয়ন্ত্রণের সাথে এই সাধারণ এএসপি.নেট বাঁধাইয়ের টুকরা:
<asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />
এখানে, SelectedDate
এর - একটি সম্পত্তি আসলে DateTime
টাইপ - এর Calendar
ওয়েব কন্ট্রোল ধরন, ও বাঁধাই পুরোপুরি কিছু নাল ফিরে আসতে পারে। অন্তর্ভুক্ত এএসপি.এনইটি জেনারেটর কোডের একটি অংশ তৈরি করবে যা উপরের কাস্ট কোডের সমান হবে। এবং NullReferenceException
এটি এমন একটি উত্থাপন করবে যা চিহ্নিত করা বেশ কঠিন, কারণ এটি এএসপি.নেট জেনারেট কোডে রয়েছে যা সূক্ষ্ম সংকলন করে ...
DateTime x = (DateTime) o as DateTime? ?? defaultValue;
এর অর্থ হ'ল প্রশ্নের মধ্যে পরিবর্তনশীলটি কিছুই দেখায় না। আমি এটি এর মতো তৈরি করতে পারি:
SqlConnection connection = null;
connection.Open();
এটি ত্রুটি ছুঁড়ে ফেলবে কারণ আমি ভেরিয়েবলটি " connection
" ঘোষণা করার পরেও এটি কোনও কিছুর প্রতি নির্দেশিত নয়। আমি যখন সদস্যটিকে " Open
" কল করার চেষ্টা করি তখন এর সমাধান করার কোনও রেফারেন্স নেই এবং এটি ত্রুটিটি ছুঁড়ে দেবে।
এই ত্রুটি এড়াতে:
object == null
।জেটব্রেইনসের পুনঃসূচনা সরঞ্জামটি আপনার কোডের এমন প্রতিটি জায়গা সনাক্ত করবে যেখানে নাল রেফারেন্স ত্রুটির সম্ভাবনা রয়েছে, আপনাকে নাল চেক করার অনুমতি দেয়। এই ত্রুটিটি বাগের এক নম্বর উত্স, আইএমএইচও।
এর অর্থ হল আপনার কোডটি কোনও অবজেক্ট রেফারেন্স ভেরিয়েবল ব্যবহার করেছে যা নালায় সেট করা হয়েছিল (যেমন এটি কোনও প্রকৃত অবজেক্টের উদাহরণটি উল্লেখ করে না)।
ত্রুটি রোধ করতে, যে বস্তুগুলি শূন্য হতে পারে সেগুলি ব্যবহারের আগে নাল পরীক্ষা করা উচিত।
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
}
সচেতন হোন যে পরিস্থিতি নির্বিশেষে কারণটি সর্বদা নেট। নেট-এ একই থাকে:
আপনি একটি রেফারেন্স ভেরিয়েবল ব্যবহার করার চেষ্টা করছেন যার মান
Nothing
/null
। যখন মানটিNothing
/null
রেফারেন্স ভেরিয়েবলের জন্য হয়, তার মানে হ'ল এটি হিপগুলিতে উপস্থিত কোনও বস্তুর উদাহরণের জন্য একটি রেফারেন্স ধারণ করে না।হয় আপনি পরিবর্তনশীল কিছু বরাদ্দ না পরিবর্তনশীল নির্ধারিত মূল্যের একটি দৃষ্টান্ত কখনো নির্মিত, অথবা আপনি পরিবর্তনশীল সেট সমান
Nothing
/null
ম্যানুয়ালি, অথবা আপনি একটি ফাংশন যে পরিবর্তনশীল সেট নামকNothing
/null
আপনার জন্য।
এই ব্যতিক্রম নিক্ষেপ করার একটি উদাহরণ হ'ল: আপনি যখন কিছু পরীক্ষা করার চেষ্টা করছেন, তখন তা বাতিল।
উদাহরণ স্বরূপ:
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 রানটাইম একটি নালারফেরান এক্সেক্সপশন নিক্ষেপ করবে যখন আপনি এমন কোনও কিছুর উপর ক্রিয়া করার চেষ্টা করবেন যা উপরের কোডটি তাত্ক্ষণিকভাবে হয়নি।
একটি আর্গুমেন্টনাল এক্সসেপশনের তুলনায় যা সাধারণত একটি প্রতিরক্ষামূলক ব্যবস্থা হিসাবে নিক্ষেপ করা হয় যদি কোনও পদ্ধতি প্রত্যাশা করে যে এতে যা পাস হচ্ছে তা শূন্য নয়।
আরও তথ্য সি # নুলারফেরান এক্সেপশন এবং নাল প্যারামিটারে রয়েছে ।
সি # 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] এর মধ্যে পার্থক্যটি জানা গুরুত্বপূর্ণ ।
সুতরাং, আপনি যদি মান ধরণের সাথে কাজ করে থাকেন তবে নালরফেরেন্সএক্সেপশনগুলি ঘটতে পারে না । যদিও আপনাকে রেফারেন্সের ধরণের সাথে সতর্কতা অবলম্বন করা দরকার !
নাম উল্লেখ করার সাথে সাথে কেবল রেফারেন্সের ধরণগুলি রেফারেন্স রাখতে পারে বা অক্ষরে অক্ষরে (বা 'নাল') নির্দেশ করতে পারে। যেখানে মান ধরণের সবসময় একটি মান থাকে।
রেফারেন্সের ধরণ (এগুলি অবশ্যই পরীক্ষা করা উচিত):
মান ধরণের (আপনি কেবল এগুলি উপেক্ষা করতে পারেন):
অপরটি 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) {
// ...
}
আপনি সেই বস্তুটি ব্যবহার করছেন যা নাল মান উল্লেখ করে। সুতরাং এটি একটি নাল ব্যতিক্রম দিচ্ছে। উদাহরণস্বরূপ স্ট্রিংয়ের মানটি নাল এবং তার দৈর্ঘ্যটি পরীক্ষা করার সময়, ব্যতিক্রম ঘটেছে।
উদাহরণ:
string value = null;
if (value.Length == 0) // <-- Causes exception
{
Console.WriteLine(value); // <-- Never reached
}
ব্যতিক্রম ত্রুটিটি হ'ল:
অপরিবর্তিত ব্যতিক্রম:
System.NullReferencesException: অবজেক্ট রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি। প্রোগ্রামে.মেন ()
যদিও কি একটি কারণ NullReferenceExceptions এবং পন্থা এড়ানোর / ঠিক যেমন একটি ব্যতিক্রম অন্যান্য উত্তর নিয়ে আলোচনা করা হয়েছে, কি অনেক প্রোগ্রামার এখনো শেখেনি কিভাবে স্বাধীনভাবে হয় ডিবাগ উন্নয়ন সময় যেমন ব্যতিক্রম।
ভিজ্যুয়াল স্টুডিওতে এটি ভিজ্যুয়াল স্টুডিও ডিবাগারকে সহজেই ধন্যবাদ জানায় ।
প্রথমে নিশ্চিত হয়ে নিন যে সঠিক ত্রুটিটি ধরা পড়ছে - দেখুন কীভাবে আমি ভিএস 2010-এ 'সিস্টেম.নুলআরফেরেন্স এক্সপেশন' ভাঙ্গতে দেব? নোট 1
তারপরে হয় ডিবাগিং (এফ 5) দিয়ে শুরু করুন বা চলমান প্রক্রিয়াতে [ভিএস ডিবাগার] সংযুক্ত করুন । উপলক্ষ্যে এটি ব্যবহারে দরকারী হতে পারে Debugger.Break
, যা ডিবাগারটি প্রবর্তন করতে অনুরোধ করবে।
এখন, যখন নালরফেরেন্সএক্সেপশন নিক্ষেপ করা হবে (বা আনহ্যান্ডল করা হয়নি) ডিবাগারটি থামিয়ে দেবে (উপরের নিয়মটি কি মনে আছে?) যে রেখায় ব্যতিক্রম ঘটেছে। কখনও কখনও ত্রুটি চিহ্নিত করা সহজ হবে।
উদাহরণস্বরূপ, নিম্নলিখিত লাইন একমাত্র কোডটি করতে ব্যতিক্রম কারণ যদি myString
মূল্যায়ন নাল করতে। এটি ওয়াচ উইন্ডোটি দেখে বা তাত্ক্ষণিক উইন্ডোতে চালিত অভিব্যক্তিগুলি দ্বারা যাচাই করা যেতে পারে ।
var x = myString.Trim();
নিম্নলিখিত হিসাবে আরও উন্নত ক্ষেত্রে, আপনাকে str1
শূন্য ছিল কিনা বা শূন্য ছিল তা নির্ধারণ করার জন্য আপনাকে উপরের কৌশলগুলির একটি (ওয়াচ বা তাত্ক্ষণিক উইন্ডোজ) ব্যবহার করতে হবে str2
।
var x = str1.Trim() + str2.Trim();
একবার যেখানে ব্যতিক্রম নিক্ষেপটি স্থাপন করা হয়েছে, নাল মানটি কোথায় [সঠিকভাবে] প্রবর্তিত হয়েছিল তা খুঁজে বের করার জন্য এটি সাধারণত পিছনের দিকে তর্ক করা তুচ্ছ -
ব্যতিক্রমটির কারণটি বুঝতে প্রয়োজনীয় সময় নিন Take নাল অভিব্যক্তি জন্য পরিদর্শন করুন। পূর্বের এক্সপ্রেশনগুলি পরিদর্শন করুন যা এর ফলে নালাগুলি প্রকাশ করতে পারে। যোগ ব্রেকপয়েন্ট যথাযথ হিসাবে প্রোগ্রামের মাধ্যমে এবং ধাপে। ডিবাগারটি ব্যবহার করুন।
1 যদি ব্রেক অন থ্রো খুব আক্রমণাত্মক হয় এবং ডিবাগারটি নেট বা তৃতীয় পক্ষের লাইব্রেরিতে একটি এনপিইতে থামায়, ব্রেক আপ ইউজার-আনহ্যান্ডলড ধরা ব্যতিক্রমগুলি সীমাবদ্ধ করতে ব্যবহার করা যেতে পারে। অতিরিক্তভাবে, ভিএস ২০১২ জাস্ট মাই কোডটি প্রবর্তন করে যা আমি পাশাপাশি সক্ষম করার প্রস্তাব দিই।
আপনি যদি জাস্ট মাই কোডটি সক্ষম করে ডিবাগ করছেন তবে আচরণটি কিছুটা আলাদা। জাস্ট মাই কোডটি সক্ষম করে, ডিবাগার প্রথমবারের সাধারণ ভাষার রানটাইম (সিএলআর) ব্যতিক্রমগুলি উপেক্ষা করে যা আমার কোডের বাইরে ফেলে দেওয়া হয় এবং আমার কোডের মধ্য দিয়ে যায় না
সাইমন মুরিয়ার এই উদাহরণ দিয়েছেন :
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<>
দৃষ্টান্তগুলির ক্ষেত্রে রানটাইম ব্যবহারের বিশেষ নিয়মের কারণে উত্থিত হয় ।
সত্তা ফ্রেমওয়ার্কে সত্তার জন্য শ্রেণীর নামটি ওয়েব ফর্ম কোড-পেছনের ফাইলের শ্রেণীর নাম হিসাবে সমেত যখন কেস যুক্ত করা হয়।
ধরুন আপনার একটি ওয়েব ফর্ম কন্টাক্ট.এএসপিএক্স রয়েছে যার কোডবিহীন ক্লাসটি যোগাযোগ এবং আপনার সত্তার নাম পরিচিতি রয়েছে।
তারপরে নীচের কোডটি আপনি প্রসঙ্গটি কল করার সময় একটি নালরফেরান এক্সেক্সশন নিক্ষেপ করবে 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 () -তে নাল রেফারেন্সএক্সেপশন দেখুন
অন্য একটি সাধারণ ক্ষেত্রে যেখানে কেউ এই ব্যতিক্রমটি পেতে পারে তাতে ইউনিট পরীক্ষার সময় মশকরা ক্লাস জড়িত। বিদ্রূপের কাঠামোটি নির্বিশেষে, আপনার অবশ্যই শ্রেণি শ্রেণিবিন্যাসের সমস্ত উপযুক্ত স্তর যথাযথভাবে উপহাস করা উচিত তা নিশ্চিত করতে হবে। বিশেষত, HttpContext
পরীক্ষার অধীনে কোড দ্বারা রেফারেন্সযুক্ত সমস্ত বৈশিষ্ট্যকে অবশ্যই উপহাস করা উচিত।
দেখুন " NullReferenceException নিক্ষিপ্ত কাস্টম AuthorizationAttribute পরীক্ষা যখন " একটি কিছুটা বাগাড়ম্বরপূর্ণ উদাহরণস্বরূপ।
এর উত্তর দেওয়ার ক্ষেত্রে আমার আলাদা দৃষ্টিভঙ্গি রয়েছে। এই ধরণের উত্তর "এড়াতে আমি আর কী করতে পারি? "
বিভিন্ন স্তর জুড়ে কাজ করার সময় , উদাহরণস্বরূপ, এমভিসি অ্যাপ্লিকেশনটিতে, একজন নিয়ামককে ব্যবসায়ের ক্রিয়াকলাপগুলি কল করার জন্য পরিষেবাগুলির প্রয়োজন হয়। এই ধরনের পরিস্থিতিতে ডিপেন্ডেন্সি ইনজেকশন কনটেইনারটি নালরফেরানএক্সেপশন এড়ানোর জন্য পরিষেবাগুলি আরম্ভ করার জন্য ব্যবহার করা যেতে পারে । সুতরাং এর অর্থ হল যে আপনাকে নাল পরীক্ষা করার বিষয়ে চিন্তা করার দরকার নেই এবং কেবল নিয়ন্ত্রকের কাছ থেকে পরিষেবাগুলি কল করতে হবে যেমন তারা সর্বদা সিঙ্গলটন বা প্রোটোটাইপ হিসাবে উপলব্ধ (এবং আরম্ভ করা) থাকবে।
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();
}
}
"এটি সম্পর্কে আমার কী করা উচিত" বিষয় সম্পর্কে অনেক উত্তর থাকতে পারে।
আপনার কোডটিতে চুক্তি করে ডিজাইন প্রয়োগ করার সময় বিকাশের সময় এ জাতীয় ত্রুটি পরিস্থিতি রোধ করার আরও একটি "আনুষ্ঠানিক" উপায় । এর অর্থ বিকাশকালে আপনার সিস্টেমে শ্রেণি আক্রমণকারী এবং / অথবা এমনকি ফাংশন / পদ্ধতি পূর্বশর্ত এবং পোস্টকন্ডিশনগুলি সেট করা দরকার ।
সংক্ষেপে, শ্রেণি আক্রমণকারীরা নিশ্চিত করে যে আপনার শ্রেণিতে এমন কিছু প্রতিবন্ধকতা থাকবে যা সাধারণ ব্যবহারে লঙ্ঘিত হবে না (এবং সুতরাং, শ্রেণিটি একটি অসামঞ্জস্যপূর্ণ অবস্থাতে পাবেন না )। পূর্ব শর্তগুলির অর্থ হ'ল কোনও ফাংশন / পদ্ধতির ইনপুট হিসাবে প্রদত্ত ডেটা অবশ্যই কিছু বাধা নির্ধারণ করে এবং সেগুলি কখনও লঙ্ঘন করে না এবং পোস্টকন্ডিশনের অর্থ কোনও ফাংশন / পদ্ধতির আউটপুট অবশ্যই সেগুলি কখনও লঙ্ঘন না করে সেট সীমাবদ্ধতা অনুসরণ করবে। চুক্তি অবস্থার উচিত না একটি বাগ মুক্ত প্রোগ্রাম চালানোর সময় লঙ্ঘন করা, অতএব চুক্তি দ্বারা ডিজাইন, ডিবাগ মোডে বাস্তবে পরীক্ষা করা হয় যখন হচ্ছে রিলিজ অক্ষম উন্নত সিস্টেমের কর্মক্ষমতা বাড়ানোর জন্য।
এইভাবে, আপনি 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 অ্যাপ্লিকেশনগুলির জন্য কোড চুক্তি প্রকল্প বিদ্যমান।
অন্যথা, চুক্তি দ্বারা নকশা ব্যবহার প্রয়োগ করা যেতে পারে গবেষকেরা ।
আপডেট: এটি উল্লেখযোগ্য যে এই শব্দটি বার্ট্র্যান্ড মায়ার তার আইফেল প্রোগ্রামিং ভাষার নকশার সাথে সংযুক্ত করে তৈরি করেছিলেন ।
একজন NullReferenceException
ফেলা হয় আমরা যখন নাল বস্তু বা যখন স্ট্রিং মান খালি হয়ে এক্সেস প্রোপার্টি করার চেষ্টা করছেন এবং আমরা এক্সেস স্ট্রিং পদ্ধতি করার চেষ্টা করছেন।
উদাহরণ স্বরূপ:
যখন খালি স্ট্রিংয়ের একটি স্ট্রিং পদ্ধতি অ্যাক্সেস করে:
string str = string.Empty;
str.ToLower(); // throw null reference exception
যখন কোনও নাল বস্তুর সম্পত্তি অ্যাক্সেস করা হয়:
Public Class Person {
public string Name { get; set; }
}
Person objPerson;
objPerson.Name /// throw Null refernce Exception
String.Empty.ToLower()
একটি নাল রেফারেন্স ব্যতিক্রম নিক্ষেপ করবে না। এটি একটি আসল স্ট্রিং উপস্থাপন করে, যদিও একটি খালি (যেমন ""
)। যেহেতু ToLower()
এটির কল করার কোনও উদ্দেশ্য রয়েছে , তাই সেখানে কোনও নাল রেফারেন্স ব্যতিক্রম ছুঁড়ে ফেলা বুদ্ধিমান হবে না।
টিএল; ডিআর: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
), তাই আমি জানি যে আমি কীভাবে মডেলটি পাঠাচ্ছিলাম তাতে ত্রুটি ছিল
এ ব্যাপারে আপনি কি করতে পারেন?
নাল রেফারেন্স কী এবং কীভাবে এটি ডিবাগ করা যায় তা ব্যাখ্যা করে এখানে অনেক ভাল উত্তর রয়েছে। তবে কীভাবে সমস্যাটি রোধ করা যায় বা কমপক্ষে এটি সহজে ধরা সহজতর করা যায় 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
ঠিকানা is
null`।
এটি দুর্দান্ত বৈশিষ্ট্য, তবে এটি আপনাকে কম তথ্য দেয়। এটি 4 টির মধ্যে কোনটি নাল তা স্পষ্ট করে না।
অন্তর্নির্মিত নল এর মতো?
সি # এর জন্য একটি দুর্দান্ত শর্টহ্যান্ড রয়েছে Nullable<T>
, আপনি এ জাতীয় ধরণের পরে একটি প্রশ্ন চিহ্ন রেখে কিছু নমনীয় করতে পারেন int?
।
এটা তোলে চমৎকার হবে যদি C # এর ভালো কিছু ছিল NotNull<T>
উপরে struct হয় এবং একটি অনুরূপ সাধারণভাবে সংক্ষেপে, হয়তো বিস্ময়বোধক বিন্দু ছিল যাতে আপনি ভালো কিছু লিখতে পারে যে (!): public void WriteName(Person! person)
।
মজার বিষয় হচ্ছে, এই পৃষ্ঠার কোনও উত্তর দুটি প্রান্তের মামলার উল্লেখ করে না, আশা করি আমি যদি এগুলি যুক্ত করি তবে কারও মনেই আসেনি:
.NET এর জেনেরিক অভিধানগুলি থ্রেড-নিরাপদ নয় এবং তারা কখনও কখনও একটি NullReference
বা এমনকি আরও ঘন ঘন নিক্ষেপ করতে পারেKeyNotFoundException
আপনি যখন দুটি সমবর্তী থ্রেড থেকে কোনও কী অ্যাক্সেস করার চেষ্টা করেন । ব্যতিক্রমটি এক্ষেত্রে বেশ বিভ্রান্তিকর।
যদি কোনও কোড NullReferenceException
দ্বারা নিক্ষেপ করা হয় তবে unsafe
আপনি আপনার পয়েন্টার ভেরিয়েবলগুলি দেখে এবং সেগুলি পরীক্ষা করতে পারেনIntPtr.Zero
বা অন্য করতে পারেন। যা একই জিনিস ("নাল পয়েন্টার ব্যতিক্রম"), তবে অনিরাপদ কোডে ভেরিয়েবলগুলি প্রায়শই মান-ধরণের / অ্যারে ইত্যাদিতে নিক্ষেপ করা হয় এবং আপনি কোনও ভ্যালু-টাইপ কীভাবে এটি নিক্ষেপ করতে পারেন তা অবাক করে ভেবে অবাক করে দেন against ব্যতিক্রম।
(যদি আপনার প্রয়োজন না হয় তবে অনিরাপদ কোডটি ব্যবহার না করার আরও একটি কারণ)
null
কোন উপায়ে আলাদা ?
আপনি নাল-কন্ডিশনাল অপারেটরগুলি সি # 6 এ ব্যবহার করে একটি পরিষ্কার উপায়ে নুলারফেরেন্সএক্সেপশন ঠিক করতে পারেন এবং নাল চেকগুলি পরিচালনা করতে কম কোড লিখতে পারেন।
সদস্য অ্যাক্সেস (?।) বা সূচক (? [) ক্রিয়াকলাপ সম্পাদনের আগে নাল পরীক্ষা করার জন্য এটি ব্যবহার করা হয়।
উদাহরণ
var name = p?.Spouse?.FirstName;
সমান:
if (p != null)
{
if (p.Spouse != null)
{
name = p.Spouse.FirstName;
}
}
ফলাফলটি হ'ল পি নাল হয়ে গেলে বা পি.স্পেস নাল হলে নামটি নাল হবে।
অন্যথায়, চলক নামটি p.Spouse.FirstName এর জন্য নির্ধারিত হবে।
আরও বিশদের জন্য: নাল-কন্ডিশনাল অপারেটর
ত্রুটি লাইন "অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণ হিসাবে সেট করা হয়নি।" সূচিত করে যে আপনি কোনও অবজেক্ট রেফারেন্সের জন্য ইনস্ট্যান্স অবজেক্ট বরাদ্দ করেননি এবং এখনও আপনি সেই বস্তুর যথাযথতা / পদ্ধতিগুলি অ্যাক্সেস করছেন।
উদাহরণস্বরূপ: ধরা যাক আপনার কাছে মাই ক্লাস নামে একটি শ্রেণি রয়েছে এবং এতে একটি সম্পত্তি প্রোপ 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;
}
}
আপনি যে শ্রেণীরটি ব্যবহার করার চেষ্টা করছেন তার কোনও বস্তু তাত্ক্ষণিকভাবে চালু না হলে নলের রেফারেন্সএক্সেপশন বা অবজেক্ট রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয় না 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 () বিবৃতিটি কার্যকর হবে, তখন এটি নালরফেরান এক্সেক্সশনটি নিক্ষেপ করবে।
ভাল, সহজ ভাষায়:
আপনি এমন কোনও বস্তু অ্যাক্সেস করার চেষ্টা করছেন যা বর্তমানে তৈরি হয়নি বা মেমরিতে নেই।
সুতরাং কিভাবে এটি মোকাবেলা:
ডিবাগ করুন এবং ডিবাগারটি বিরতি দিন ... এটি আপনাকে ভাঙা ভেরিয়েবলটিতে সরাসরি নিয়ে যাবে ... এখন আপনার কাজটি কেবল এটি ঠিক করা ঠিক আছে ... উপযুক্ত জায়গায় নতুন কীওয়ার্ডটি ব্যবহার করে ।
যদি এটি কিছু ডাটাবেস কমান্ডের কারণে ঘটে থাকে কারণ বস্তুটি উপস্থিত না থাকে তবে আপনাকে যা করতে হবে তা হল একটি নাল চেক করা এবং এটি পরিচালনা করা:
if (i == null) {
// Handle this
}
সবচেয়ে শক্ত একটি .. যদি জিসি ইতিমধ্যে বস্তুটি সংগ্রহ করে ... সাধারণত আপনি যদি স্ট্রিং ব্যবহার করে কোনও বিষয় সন্ধান করার চেষ্টা করছেন এটি ঘটে ... এটি হ'ল বস্তুর নাম অনুসারে এটি সন্ধান করতে পারে তবে জিসি ইতিমধ্যে হতে পারে এটি পরিষ্কার করে দেওয়া ... এটি খুঁজে পাওয়া শক্ত এবং বেশ সমস্যা হয়ে উঠবে ... এটি মোকাবেলার জন্য আরও ভাল উপায় বিকাশ প্রক্রিয়া চলাকালীন যেখানে প্রয়োজন সেখানে নাল চেক করা। এটি আপনার অনেক সময় সাশ্রয় করবে।
নাম অনুসারে সন্ধান করার অর্থ আমার অর্থ কিছু ফ্রেমওয়ার্ক আপনাকে স্ট্রিং এবং কোড ব্যবহার করে FIndObજેક્ટগুলিতে অনুমতি দেয়: FindObject ("অবজেক্টনাম");
আক্ষরিক অর্থে নুলারফেরান এক্সেপশনটি ঠিক করার সবচেয়ে সহজ উপায় দুটি উপায়। আপনার যদি গেমস অবজেক্ট উদাহরণস্বরূপ স্ক্রিপ্ট সংযুক্ত থাকে এবং একটি আরবি নামক ভেরিয়েবল (rigidbody) থাকে তবে আপনি যখন আপনার খেলা শুরু করবেন তখন এই পরিবর্তনশীলটি শূন্য হয়ে যাবে।
এই কারণেই আপনি একটি নালরফেরানএক্সেপশন পান কারণ কম্পিউটারে সেই পরিবর্তনশীলটিতে ডেটা সংরক্ষণ করা হয় না।
আমি উদাহরণ হিসাবে একটি রিগিডবডি ভেরিয়েবল ব্যবহার করব।
আমরা আসলে কয়েকটি উপায়ে সহজেই ডেটা যুক্ত করতে পারি:
rb = GetComponent<Rigidbody>();
Start()
বা Awake()
ফাংশনের অধীনে সবচেয়ে ভাল কাজ করে। rb = AddComponent<RigidBody>();
আরও নোট: আপনি যদি object [RequireComponent(typeof(RigidBody))]
ক্যটি আপনার সামগ্রীতে কোনও উপাদান যুক্ত করতে চান এবং আপনি একটি যুক্ত করতে ভুলে যেতে পারেন তবে আপনি আপনার শ্রেণীর ঘোষণার উপরে (আপনার সমস্ত ব্যবহারের নীচে স্থান) টাইপ করতে পারেন ।
গেমস উপভোগ করুন এবং মজা করুন!
যদি আমরা সাধারণ পরিস্থিতি বিবেচনা করি যেখানে এই ব্যতিক্রমটি ছুঁড়ে ফেলা যায়, শীর্ষে উইনিং অবজেক্টগুলিতে অ্যাক্সেস করা।
উদা:
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
এটি মূলত একটি নাল রেফারেন্স ব্যতিক্রম । মাইক্রোসফ্ট যেমন বলেছে-
আপনি কোনও ধরণের সদস্যের অ্যাক্সেস করার চেষ্টা করার সময় একটি নালরফেরানএক্সেপশন ব্যতিক্রম ছুঁড়ে দেওয়া হয় যার মূল্য নাল।
এর অর্থ যদি কোনও সদস্যের কোনও মূল্য থাকে না এবং আমরা সেই সদস্যকে নির্দিষ্ট কাজ সম্পাদনের জন্য তৈরি করে দিই তবে সিস্টেম নিঃসন্দেহে একটি বার্তা টস করবে এবং বলে-
"আরে অপেক্ষা করুন, সেই সদস্যের কোনও মূল্য নেই তাই এটি যে কাজটি আপনি এটি অর্পণ করছেন তা সম্পাদন করতে পারে না।"
ব্যতিক্রম নিজেই বলে যে কিছু উল্লেখ করা হচ্ছে তবে যার মান সেট করা হচ্ছে না। সুতরাং এটি নির্দেশ করে যে এটি কেবলমাত্র রেফারেন্স প্রকারগুলি ব্যবহার করার সময় ঘটে যখন মান প্রকারগুলি অ-অযোগ্য।
আমরা যদি ভ্যালু টাইপের সদস্য ব্যবহার করি তবে নালরফেরানএক্সেপশনটি ঘটবে না।
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");
}
}
উপরের কোডটির জন্য সংকলক একটি ত্রুটি উত্থাপন করে যা ভেরিয়েবল অজেক্টকে নিযুক্ত করা হয় যা আমাদের ভেরিয়েবলের নাল মান বা কিছুই নেই তা বোঝায়। উপরের কোডটির জন্য সংকলক একটি ত্রুটি উত্থাপন করে যা ভেরিয়েবল অজেক্টকে নিযুক্ত করা হয় যা আমাদের ভেরিয়েবলের নাল মান বা কিছুই নেই তা বোঝায়।
বস্তুর মান পরীক্ষা না করার জন্য আমাদের ত্রুটির কারণে নুলরেফারেন্সএক্সেপশন উত্থিত হয়। আমরা প্রায়শই কোড বিকাশে অবজেক্টের মানগুলি চেক না করে রেখে দেই।
যখন আমরা আমাদের অবজেক্টগুলি ইনস্ট্যান্ট করতে ভুলে যাই তখনও এটি উত্থাপিত হয়। পদ্ধতি, বৈশিষ্ট্য, সংগ্রহ ইত্যাদি ব্যবহার করা যা নাল মানগুলি ফিরিয়ে দিতে বা সেট করতে পারে তাও এই ব্যতিক্রমের কারণ হতে পারে।
এই নামী ব্যতিক্রম এড়ানোর জন্য বিভিন্ন উপায় এবং পদ্ধতি রয়েছে:
সুস্পষ্ট চেকিং: বস্তু, বৈশিষ্ট্য, পদ্ধতি, অ্যারে এবং সংগ্রহগুলি নাল কিনা তা আমাদের চেক করার traditionতিহ্যটি মেনে চলতে হবে। এটি কেবল শর্তাধীন বিবৃতি যেমন যদি-অন্যথায় অন্যথায় ইত্যাদি ব্যবহার করে প্রয়োগ করা যেতে পারে etc.
ব্যতিক্রম হ্যান্ডলিং: এই ব্যতিক্রম পরিচালনার অন্যতম গুরুত্বপূর্ণ উপায়। সাধারণ চেষ্টা-অবশেষে অবরুদ্ধ ব্লকগুলি ব্যবহার করে আমরা এই ব্যতিক্রমটি নিয়ন্ত্রণ করতে পারি এবং এটির লগও বজায় রাখতে পারি। আপনার অ্যাপ্লিকেশন উত্পাদন পর্যায়ে থাকলে এটি খুব কার্যকর হতে পারে।
নাল অপারেটর: নাল কোলেসিং অপারেটর এবং নাল কন্ডিশনাল অপারেটরগুলি অবজেক্টস, ভেরিয়েবল, বৈশিষ্ট্য এবং ক্ষেত্রগুলিতে মান নির্ধারণের ক্ষেত্রেও ব্যবহৃত হতে পারে।
ডিবাগার: বিকাশকারীদের জন্য, আমাদের সাথে ডিবাগিংয়ের বড় অস্ত্র রয়েছে। বিকাশের সময় যদি আমরা নালরফেরেন্সএক্সেপশনের মুখোমুখি হয়ে থাকি তবে আমরা ব্যতিক্রমের উত্সে পেতে ডিবাগারটি ব্যবহার করতে পারি।
অন্তর্নির্মিত পদ্ধতি: সিস্টেম পদ্ধতি যেমন গেটভ্যালিঅরডেফল্ট (), ইসনুলআরওহাইটস্পেস () এবং ইসনুলারএম্প্টি () নালগুলির জন্য পরীক্ষা করে এবং যদি কোনও নাল মান থাকে তবে ডিফল্ট মান নির্ধারণ করে।
ইতিমধ্যে এখানে অনেক ভাল উত্তর রয়েছে। আপনি আমার ব্লগে উদাহরণ সহ আরও বিশদ বিবরণ পরীক্ষা করতে পারেন ।
আশা করি এটিও সাহায্য করবে!
বিল্ডটি সংরক্ষণ বা সংকলনের সময় যদি কেউ এই বার্তাটি পেয়ে থাকেন তবে কেবলমাত্র সমস্ত ফাইল বন্ধ করুন এবং তারপরে যেকোন ফাইল সংকলন এবং সংরক্ষণের জন্য খুলুন।
আমার জন্য কারণটি ছিল যে আমি ফাইলটির নতুন নামকরণ করেছি এবং পুরানো ফাইলটি এখনও খোলা ছিল।