NullReferenceException යනු කුමක්ද, මම එය නිවැරදි කරන්නේ කෙසේද?


1874

මට යම් කේතයක් ඇති අතර එය ක්‍රියාත්මක වන විට එය NullReferenceExceptionමෙසේ විසි කරයි .

වස්තු සමුද්දේෂය වස්තුවක උදාහරණයකට පිහිටුවා නැත.

මෙයින් අදහස් කරන්නේ කුමක්ද, මෙම දෝෂය නිවැරදි කිරීමට මට කුමක් කළ හැකිද?


VS 2017 හි ව්‍යතිරේක සහායකයා මෙම ව්‍යතිරේකයට හේතුව හඳුනා ගැනීමට වඩාත් ප්‍රයෝජනවත් වනු ඇත - new Exception Helper යටතේ blogs.msdn.microsoft.com/visualstudio/2016/11/28/… .
සෙව් ස්පිට්ස්

හිතවත් අනාගත අමුත්තන්, මෙම ප්‍රශ්නයට පිළිතුරු ArgumentNullException සඳහා සමානවම අදාළ වේ . ඔබගේ ප්‍රශ්නය මෙහි අනුපිටපතක් ලෙස වසා දමා ඇති අතර ඔබ ANE එකක් අත්විඳින්නේ නම්, කරුණාකර නිදොස් කිරීම සඳහා පිළිතුරු වල උපදෙස් අනුගමනය කර ඔබේ ගැටලුව විසඳන්න.

ANWE සිදුවිය යුත්තේ ශුන්‍යය පරාමිතියක් ලෙස සම්මත වුවහොත් පමණි. මෙම ප්‍රශ්නයේ අනුපිටපතක් ලෙස ANE ප්‍රශ්නයක් වසා තිබේ නම් ඔබට උදාහරණයක් දිය හැකිද?
ජෝන් සෝන්ඩර්ස්

එය මෙටා මතට ​​පැමිණියේය, නමුත් මට සබැඳිය කැණීමට යා යුතුය. නමුත් එම අදහස් දැක්වීමට අනුව, ANE යනු හුදෙක් NRE ය, නමුත් යමෙකු පූර්වගාමී චෙක්පතක් එක් කළ අතර, ඔබ අවම වශයෙන් හරියටම ශුන්‍යය කුමක්දැයි දනී (තර්කයේ නම සපයා ඇත), එබැවින් කෙළින්ම ඉහළට එන NRE ට වඩා රෝග විනිශ්චය කිරීම ටිකක් පහසුය.

Answers:


2429

හේතුව කුමක්ද?

බොටම් ලයින්

ඔබ උත්සාහ කරන්නේ null(හෝ NothingVB.NET හි) යමක් භාවිතා කිරීමට ය . මෙයින් අදහස් කරන්නේ ඔබ එය සකසා ඇති බවයි null, නැතහොත් ඔබ එය කිසිසේත් කිසිසේත් සකසා නැත.

වෙනත් ඕනෑම දෙයක් මෙන්, nullවටේට ගමන් කරයි. එය නම් null දී ක්රමය "A", එය, එම කමෙව්දය විය හැකි 'බී' සම්මත null කිරීමට ක්රමයක් "A".

null විවිධ අර්ථයන් තිබිය හැකිය:

    1. කරන වස්තුව විචල්ය uninitialized සහ ඒ නිසා කිසිම දෙයක් වන බවයි. මෙම අවස්ථාවේ දී, ඔබ එවැනි වස්තූන්ගේ ගුණාංග හෝ ක්‍රම වෙත ප්‍රවේශ වන්නේ නම්, එය a NullReferenceException.
    1. අර්ථවත් වටිනාකමක් නොමැති බව දැක්වීමට සංවර්ධකයා හිතාමතාම භාවිතා nullකරයි. C # විචල්යයන් සඳහා ශුන්‍ය දත්ත සමුදායන් පිළිබඳ සංකල්පයක් ඇති බව සලකන්න (දත්ත සමුදා වගු වල ශුන්‍ය ක්ෂේත්ර තිබිය හැකිය) - nullඑහි කිසිදු වටිනාකමක් ගබඩා කර නොමැති බව දැක්වීමට ඔබට ඒවා පැවරිය හැකිය , උදාහරණයක් ලෙස int? a = null;ප්රශ්න ලකුණ මඟින් එය ශුන්ය ලෙස ගබඩා කිරීමට ඉඩ දී ඇත විචල්ය a. ඔබට එය සමඟ if (a.HasValue) {...}හෝ සමඟ පරීක්ෂා කළ හැකිය if (a==null) {...}. ශුන්‍ය විචල්‍යයන්, aමෙම උදාහරණය මෙන් , a.Valueපැහැදිළිව හෝ සාමාන්‍ය මාර්ගයෙන් වටිනාකමට ප්‍රවේශ වීමට ඉඩ දෙයි a.
      සටහන හරහා එය ප්රවේශ බව a.Valueක අවුලට InvalidOperationExceptionවෙනුවට ක NullReferenceExceptionනම් aකියන්නේnull- ඔබ කලින්ම චෙක්පත කළ යුතුය, එනම් ඔබට වෙනත් විචල්‍ය විචල්‍යයක් තිබේ int b;නම් ඔබ කළ යුත්තේ if (a.HasValue) { b = a.Value; }කෙටි හෝ ඊට අඩු පැවරුම් ය if (a != null) { b = a; }.

මෙම ලිපියේ ඉතිරි කොටස වඩාත් සවිස්තරාත්මකව දක්වා ඇති අතර බොහෝ ක්‍රමලේඛකයින් බොහෝ විට කරන වැරදි පෙන්වයි NullReferenceException.

වඩාත් විශේෂිතව

මෙම runtimeවීසි වූ NullReferenceException සෑම විටම එකම දෙයක් අදහස්: ඔබ සඳහන් භාවිතා කිරීමට උත්සාහ කර ඇති අතර, මෙම යොමු ආරම්භනය නැත (හෝ එය විය වරක් ආරම්භනය, නමුත් තව දුරටත් ආරම්භනය).

මෙයින් අදහස් කරන්නේ යොමු කිරීම nullවන අතර, ඔබට nullයොමු කිරීමක් හරහා සාමාජිකයින්ට (ක්‍රම වැනි) ප්‍රවේශ විය නොහැක . සරලම අවස්ථාව:

string foo = null;
foo.ToUpper();

මෙය NullReferenceExceptionදෙවන පේළියට විසි කරනු ඇත, මන්දයත් ඔබට යොමු ක්‍රමය ToUpper()වෙත stringයොමු කිරීමේ ක්‍රමය ඇමතිය නොහැකි බැවිනි null.

නිදොස්කරණය

A හි ප්‍රභවය ඔබ සොයා ගන්නේ කෙසේද NullReferenceException? මීට අමතරව විෂුවල් ස්ටුඩියෝ දී දෝෂහරණ පොදු නීති අදාළ වන්නේ නම්, එය සිදුවන ස්ථානයේ දී හරියටම දමනු ලැබේ වන ව්යතිරේකයක් ම දෙස බලා, සිට: ස්ථානය මූලෝපායාත්මක breakpoints හා ඔබගේ විචල්ය පරීක්ෂා විවර නම්, ඔවුන්ෙග් නම් පුරා මූසිකය ඩොලරයක විසින් එක්කෝ, ( ඉක්මන්) කවුළුව නරඹන්න හෝ ස්ථාන සහ ඔටෝස් වැනි විවිධ නිදොස් කිරීමේ පැනල් භාවිතා කරන්න.

ඔබට සඳහන කොතැනදැයි සොයා ගැනීමට අවශ්‍ය නම්, එහි නම දකුණු-ක්ලික් කර "සියලු යොමු සොයන්න" තෝරන්න. එවිට ඔබට සොයාගත් සෑම ස්ථානයකම බ්‍රේක්පොයින්ට් එකක් තැබිය හැකි අතර, නිදොස් කර ඇති ඔබේ වැඩසටහන ක්‍රියාත්මක කරන්න. එවැනි කඩාවැටීමක් මත නිදොස්කරණය බිඳෙන සෑම අවස්ථාවකම, ඔබ යොමු කිරීම ශුන්‍ය නොවන බව තීරණය කළ යුතුද, විචල්‍යය පරීක්ෂා කර, ඔබ එය අපේක්ෂා කරන අවස්ථාවකට එය යොමු කරනවාද යන්න තහවුරු කර ගත යුතුය.

ක්‍රමලේඛ ප්‍රවාහය මේ ආකාරයෙන් අනුගමනය කිරීමෙන්, උදාහරණය අහෝසි නොවිය යුතු ස්ථානය සහ එය නිසි ලෙස සකසා නොතිබීමට හේතුව සොයාගත හැකිය.

උදාහරණ

ව්‍යතිරේකය විසි කළ හැකි පොදු අවස්ථා කිහිපයක්:

සාමාන්‍ය

ref1.ref2.ref3.member

Ref1 හෝ ref2 හෝ ref3 අහෝසි නම් ඔබට ලැබෙනු ඇත NullReferenceException. ඔබට ගැටළුව විසඳීමට අවශ්‍ය නම්, ප්‍රකාශනය එහි සරල සමානතාවයට නැවත ලිවීමෙන් ශුන්‍ය වන්නේ කුමක්දැයි සොයා බලන්න:

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

නිශ්චිතවම, දී HttpContext.Current.User.Identity.Name, HttpContext.Currentශුන්‍ය විය හැකිය, නැතහොත් Userදේපල අහෝසි විය හැකිය, නැතහොත් Identityදේපල අහෝසි විය හැකිය.

වක්ර

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

ඔබට දරුවාගේ (පුද්ගල) ශුන්‍ය යොමුව මග හැරීමට අවශ්‍ය නම්, ඔබට එය මව් (පොත්) වස්තුවෙහි ඉදිකිරීම්කරු තුළ ආරම්භ කළ හැකිය.

කැදැලි වස්තු ආරම්භකයින්

කැදැලි වස්තු ආරම්භකයින් සඳහා ද මෙය අදාළ වේ:

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

මෙය පරිවර්තනය කරයි

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

කරන අතර newමූලික වචන භාවිතා වන අතර, එය පමණක් නව උදාහරණයක් නිර්මාණය Bookනව උදාහරණයක් වශයෙන්, නමුත් Person, එසේ Authorදේපල තවමත් null.

කැදැලි එකතු කිරීමේ ආරම්භකයින්

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

කැදැලි එකතුව Initializersඑක හා සමානයි:

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

මෙය පරිවර්තනය කරයි

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

මෙම new Personපමණක් වන උදාහරණයක් නිර්මාණය Person, නමුත් Booksඑකතුව තවමත් null. එකතු කිරීමේ Initializerවාක්‍ය ඛණ්ඩය සඳහා එකතුවක් නිර්මාණය නොකරයි p1.Books, එය පරිවර්තනයට පරිවර්තනය කරයි p1.Books.Add(...).

අරාව

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

අරා මූලද්රව්ය

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

හකුරු අරා

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. 

පොදු පංතිය Form1 {පුද්ගලික පාරිභෝගික පාරිභෝගිකයා;

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

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

}

අවධාරනය කළ ක්ෂේත්‍ර සමඟ උපසර්ග ක්ෂේත්‍රයන් සඳහා වන සම්මුතිය අනුගමනය කිරීමෙන් මෙය විසඳා ගත හැකිය:

    private Customer _customer;

ASP.NET පිටුව ජීවන චක්‍රය:

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

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

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

ASP.NET සැසි අගයන්

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

ASP.NET MVC හිස් දර්ශන ආකෘති

ක දේපල පිලිබඳව සඳහන් කරන විට හැර සිදුවන්නේ නම් @Modelතුළ සිටින ASP.NET MVC View, ඔබ බව තේරුම් ගත යුතු වෙනවා Modelවිට ඔබ, ඔබගේ ක්රියාව ක්රමය තුළ තබා ලක්වෙයි returnදැක්ම. ඔබගේ පාලකයෙන් හිස් ආකෘතියක් (හෝ ආදර්ශ දේපල) ඔබ ආපසු ලබා දෙන විට, දර්ශන එයට ප්‍රවේශ වන විට ව්‍යතිරේකය සිදු වේ:

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

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

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

WPF පාලන නිර්මාණ නියෝගය සහ සිදුවීම්

WPFInitializeComponentදෘශ්‍ය ගසෙහි දිස්වන අනුපිළිවෙලට ඇමතුම අතරතුර පාලනයන් නිර්මාණය වේ. NullReferenceExceptionසිදුවීම් හසුරුවන්නන් යනාදිය සමඟ කලින් සාදන ලද පාලනයන් සම්බන්ධයෙන් A මතු කරනු ඇත 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()විසි කිරීම් ව්‍යතිරේක. "OrDefault" අනුවාදයන් එම අවස්ථාවේ දී අහෝසි වේ. එබැවින් ඒ ගැන සැලකිලිමත් වන්න.

foreach

foreachඔබ ශුන්‍ය එකතු කිරීම නැවත කිරීමට උත්සාහ කරන විට විසි කරයි. nullඑකතු කිරීම් ආපසු ලබා දෙන ක්‍රම වලින් බලාපොරොත්තු නොවූ ප්‍රති result ලයක් නිසා සාමාන්‍යයෙන් සිදු වේ.

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

වඩාත් යථාර්ථවාදී උදාහරණය - XML ​​ලේඛනයෙන් නෝඩ් තෝරන්න. නෝඩ් සොයාගත නොහැකි නම් විසි කරනු ඇත, නමුත් ආරම්භක නිදොස්කරණය මඟින් සියලු ගුණාංග වලංගු බව පෙන්නුම් කරයි:

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

වළක්වා ගත හැකි ක්‍රම

nullශුන්‍ය අගයන් පැහැදිලිව පරීක්ෂා කර නොසලකා හරින්න.

සමහර විට යොමුව අහෝසි වනු ඇතැයි ඔබ අපේක්ෂා කරන්නේ නම්, nullඋදාහරණ සාමාජිකයින්ට ප්‍රවේශ වීමට පෙර එය තිබේදැයි පරීක්ෂා කළ හැකිය :

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

පැහැදිළිව පරීක්ෂා කර nullපෙරනිමි අගයක් ලබා දෙන්න.

උදාහරණයක් ලෙස නැවත පැමිණීමට ඔබ අපේක්ෂා කරන ක්‍රම ඇමතුම් මඟින් ආපසු යා හැකිය null, උදාහරණයක් ලෙස සොයන වස්තුව සොයාගත නොහැකි වූ විට. මෙය සිදු වූ විට පෙරනිමි අගයක් ලබා දීමට ඔබට තෝරා ගත හැකිය:

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

nullක්‍රම ඇමතුම් වලින් පැහැදිලිව පරීක්ෂා කර අභිරුචි ව්‍යතිරේකයක් විසි කරන්න.

ඔබට අභිරුචි ව්‍යතිරේකයක් විසි කළ හැකිය, එය ඇමතුම් කේතයට හසු කර ගැනීම සඳහා පමණි:

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

ව්‍යතිරේකය සිදුවීමට පෙර ගැටලුව හසු කර ගැනීම Debug.Assertසඳහා අගයක් කිසි විටෙකත් නොවිය යුතු නම් භාවිතා කරන්න null.

සංවර්ධනයේ දී ක්‍රමවේදයක් විය හැකි නමුත් කිසි විටෙකත් ආපසු නොයා යුතු බව ඔබ දන්නා විට, එය සිදු වූ විට හැකි ඉක්මනින් කැඩීමට nullඔබට භාවිතා කළ හැකිය Debug.Assert():

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

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

    // Some other code

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

මෙම චෙක්පත ඔබගේ මුදාහැරීමේ නිමැවුමෙන් අවසන් නොවනු ඇත , එය ක්‍රියාත්මක වන විට මුදා හැරීමේ ප්‍රකාරයේදී NullReferenceExceptionනැවත විසි කිරීමට හේතු book == nullවේ.

පෙරනිමි අගයක් ඇති විට ඒවා ලබා දීමට අගය වර්ග GetValueOrDefault()සඳහා භාවිතා කරන්න .nullablenull

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

ශුන්‍ය සිසිලන ක්‍රියාකරු භාවිතා කරන්න: ??[C #] හෝ If()[VB].

nullහමු වූ විට පෙරනිමි අගයක් සැපයීමේ කෙටිමං :

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

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

ශුන්‍ය තත්ව ක්‍රියාකරු භාවිතා කරන්න: ?.හෝ ?[x]අරා සඳහා (C # 6 සහ VB.NET 14 හි ඇත):

මෙය සමහර විට ආරක්ෂිත සංචලනය හෝ එල්විස් (එහි හැඩයට පසුව) ක්‍රියාකරු ලෙසද හැඳින්වේ. ක්රියාකරුගේ වම් පැත්තේ ප්රකාශය ශූන්‍ය නම්, දකුණු පස තක්සේරු නොකෙරේ, ඒ වෙනුවට ශූන්‍යය ආපසු දෙනු ලැබේ. ඒ කියන්නේ මෙවැනි අවස්ථා:

var title = person.Title.ToUpper();

පුද්ගලයාට මාතෘකාවක් නොමැති නම්, මෙය ව්‍යතිරේකයක් වනු ඇත්තේ එය ToUpperශුන්‍ය වටිනාකමක් ඇති දේපලක් ඉල්ලා සිටීමට උත්සාහ කරන බැවිනි .

ඇතුළත C# 5සහ පහළින්, මෙය ආරක්ෂා කළ හැකිය:

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

ව්‍යතිරේකයක් විසි කරනවා වෙනුවට දැන් මාතෘකාව විචල්‍යය ශුන්‍ය වනු ඇත. C # 6 මේ සඳහා කෙටි වාක්‍ය ඛණ්ඩයක් හඳුන්වා දෙයි:

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

මෙම මාතෘකාව විචල්ය කිරීම සිදුවනු ඇත null, සහ වන ලෙස ඉල්ලා ToUpperනම් කර නොමැති person.Titleවේ null.

ඇත්ත වශයෙන්ම, පෙරනිමි අගයක් සැපයීම සඳහා ඔබ තවමත්title ශුන්‍යය පරීක්ෂා කර බැලිය යුතුය. නැතහොත් ශුන්‍ය තත්ව ක්‍රියාකරු ( ??) සමඟ ශුන්‍ය සිසිලන ක්‍රියාකරු ( ) භාවිතා කළ යුතුය:

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

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

ඒ හා සමානව, අරා සඳහා ඔබට ?[i]පහත පරිදි භාවිතා කළ හැකිය :

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

මෙය පහත සඳහන් දේ කරයි: myIntArrayශුන්‍ය නම් , ප්‍රකාශනය ශුන්‍ය වන අතර ඔබට එය ආරක්ෂිතව පරීක්ෂා කළ හැකිය. එහි අරාවක් තිබේ නම්, එය පහත පරිදි වේ: elem = myIntArray[i];සහ i<sup>th</sup>මූලද්‍රව්‍යය නැවත ලබා දෙයි .

ශුන්‍ය සන්දර්භය භාවිතා කරන්න (C # 8 හි ඇත):

එහි හඳුන්වා දී C# 8ඇත්තේ ශුන්‍ය සන්දර්භය සහ අහෝසි කළ හැකි විමර්ශන වර්ග විචල්‍යයන් පිළිබඳ ස්ථිතික විශ්ලේෂණයක් සිදු කරන අතර අගයක් ශුන්‍ය විය හැකි හෝ ශුන්‍ය ලෙස සකසා තිබේ නම් සම්පාදක අනතුරු ඇඟවීමක් සපයයි. අහෝසි කළ හැකි විමර්ශන වර්ග මඟින් ශුන්‍ය වීමට පැහැදිලිවම ඉඩ ලබා දේ.

Nullableඔබගේ csprojගොනුවේ ඇති මූලද්‍රව්‍යය භාවිතා කරමින් ව්‍යාපෘතියක් සඳහා ශුන්‍ය විවරණ සන්දර්භය සහ අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය සැකසිය හැකිය . මෙම මූලද්‍රව්‍යය සම්පාදකයා විසින් වර්ග වල ශුන්‍යතාවය අර්ථ නිරූපණය කරන්නේ කෙසේද සහ කුමන අනතුරු ඇඟවීම් ජනනය කරයිද යන්න වින්‍යාස කරයි. වලංගු සැකසුම්:

  • සක්‍රීය කරන්න: විවරණය කළ හැකි විවරණ සන්දර්භය සක්‍රීය කර ඇත. අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය සක්‍රීය කර ඇත. විමර්ශන වර්ගයක විචල්‍යයන්, නිදසුනක් ලෙස නූල්, අහෝසි කළ නොහැක. සියලු අවලංගු කිරීමේ අනතුරු ඇඟවීම් සක්‍රීය කර ඇත.
  • අක්‍රීය කරන්න: අහෝසි කළ හැකි විවරණ සන්දර්භය අක්‍රීය කර ඇත. අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය අක්‍රීය කර ඇත. C # හි පෙර සංස්කරණ මෙන්, විමර්ශන වර්ගයක විචල්‍යයන් නොසලකා හරිනු ලැබේ. සියලු අවලංගු කිරීමේ අනතුරු ඇඟවීම් අක්‍රීය කර ඇත.
  • ආරක්ෂිතව: විවරණය කළ හැකි විවරණ සන්දර්භය සක්‍රීය කර ඇත. අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය ආරක්ෂිතයි. විමර්ශන වර්ගයක විචල්‍යයන් අහෝසි කළ නොහැක. සියලුම ආරක්‍ෂිත අවලංගු කිරීමේ අනතුරු ඇඟවීම් සක්‍රීය කර ඇත.
  • අනතුරු ඇඟවීම්: විවරණය කළ හැකි විවරණ සන්දර්භය අක්‍රීය කර ඇත. අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය සක්‍රීය කර ඇත. විමර්ශන වර්ගයක විචල්‍යයන් නොසලකා හරිනු ලැබේ. සියලු අවලංගු කිරීමේ අනතුරු ඇඟවීම් සක්‍රීය කර ඇත.
  • safeonlywarnings: අහෝසි කළ හැකි විවරණ සන්දර්භය අක්‍රීය කර ඇත. අවලංගු කළ හැකි අනතුරු ඇඟවීමේ සන්දර්භය ආරක්ෂිතයි. විමර්ශන වර්ගයක විචල්‍යයන් නොසලකා හරිනු ලැබේ. සියලුම ආරක්‍ෂිත අවලංගු කිරීමේ අනතුරු ඇඟවීම් සක්‍රීය කර ඇත.

ශුන්‍ය අගය වර්ග වලට සමාන වාක්‍ය ඛණ්ඩයක් භාවිතා කරමින් ශුන්‍ය යොමු වර්ගයක් සටහන් කර ඇත: a ?විචල්‍යයේ වර්ගයට එකතු වේ.

ඉරේටර වල ඇති ශුන්‍ය විරූපණයන් නිදොස් කිරීම සහ සවි කිරීම සඳහා විශේෂ ක්‍රම

C#"iterator block" සඳහා සහය දක්වයි (වෙනත් ජනප්‍රිය භාෂාවලින් "ජනක යන්ත්‍ර" ලෙස හැඳින්වේ). විලම්බිත ක්‍රියාත්මක කිරීම හේතුවෙන් ශුන්‍ය විරූපණ ව්‍යතිරේකයන් ඉටරේටර් බ්ලොක් වල නිදොස් කිරීම සඳහා විශේෂයෙන් උපක්‍රමශීලී විය හැකිය:

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

මෙය වැරදි ඇයි? Iterator වාරණය ඇත්ත වශයෙන්ම ක්‍රියාත්මක වන තෙක් 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 ධාවන වේලාව පසුව මෙම දෝෂය හඳුනාගෙන එය ශුන්‍ය විරූපණ ව්‍යතිරේකයක් බවට පත් කරයි.

ශුන්‍ය දර්ශකයක් සහ ශුන්‍ය යොමු කිරීමක් යන දෙකම අවලංගු කිරීම එකම ව්‍යතිරේකයක් ඇති කරන්නේ එබැවිනි.

දෙවන කරුණ ගැන කුමක් කිව හැකිද? Dereferencing ඕනෑම අථත්ය මතකයක් අඩුම පිටුවේ වැටෙන අවලංගු පහිටුම් දක්වනය එම මෙහෙයුම් පද්ධතිය දෝෂ ඇතිවිය හා එමගින් එම හැර.

මෙය අර්ථවත් වන්නේ ඇයි? හොඳයි, අපට අඟල් දෙකක් අඩංගු ව්‍යුහයක් සහ ශුන්‍යයට සමාන කළමණාකරනය නොකළ දර්ශකයක් ඇතැයි සිතමු. අපි ව්‍යුහයේ දෙවන අන්තය අවලංගු කිරීමට උත්සාහ කරන්නේ නම්, CLRශුන්‍ය ස්ථානයේ ඇති ගබඩාවට ප්‍රවේශ වීමට උත්සාහ නොකරනු ඇත; එය හතරවන ස්ථානයේ ගබඩාවට පිවිසෙනු ඇත. නමුත් තර්කානුකූලව මෙය ශුන්‍ය විරූපණයකි, මන්ද අප එම ලිපිනයට ශුන්‍ය හරහා පිවිසෙන බැවිනි .

ඔබ අනාරක්ෂිත කේතයක් සමඟ වැඩ කරන්නේ නම් සහ ඔබට ශුන්‍ය විරූපණ ව්‍යතිරේකයක් ලැබෙන්නේ නම්, වරදකාරී දර්ශකය අහෝසි නොවිය යුතු බව මතක තබා ගන්න. එය පහළම පිටුවෙහි ඕනෑම ස්ථානයක් විය හැකි අතර මෙම ව්‍යතිරේකය නිපදවනු ඇත.


55
සමහර විට මෙය ගොළු අදහස් දැක්වීමක් විය හැකි නමුත් මෙම ගැටළුව වළක්වා ගත හැකි පළමු හා හොඳම ක්‍රමය වස්තුව ආරම්භ කිරීම නොවේද? මට මෙම දෝෂය සිදුවුවහොත් එය සාමාන්‍යයෙන් සිදුවන්නේ අරාව මූලද්‍රව්‍යය වැනි දෙයක් ආරම්භ කිරීමට මට අමතක වූ බැවිනි. වස්තුව ශුන්‍ය යැයි අර්ථ දැක්වීම හා එය යොමු කිරීම වඩා අඩු පොදු යැයි මම සිතමි. විස්තරයට යාබදව ඇති සෑම ගැටලුවක්ම විසඳීමට මාර්ගය ලබා දෙන්න. තවමත් හොඳ තනතුරක්.
ජේපීකේ

30
කිසියම් වස්තුවක් නොමැති නම්, නමුත් ක්‍රමයකින් හෝ දේපලකින් ලැබෙන ප්‍රතිලාභ වටිනාකම කුමක් ද?
ජෝන් සෝන්ඩර්ස්

6
පොත / කර්තෘගේ උදාහරණය ටිකක් අමුතුයි .... එය සම්පාදනය කරන්නේ කෙසේද? Intellisense පවා ක්‍රියා කරන්නේ කෙසේද? මොකක්ද මම පරිගණකය සමඟ හොඳ නැහැ ...

5
Ill විල්: මගේ අවසන් සංස්කරණය උදව් වේද? එසේ නොවේ නම්, කරුණාකර ඔබ ගැටලුවක් ලෙස දකින දේ ගැන වඩාත් පැහැදිලි වන්න.
ජෝන් සෝන්ඩර්ස්

6
O ජෝන් සොන්ඩර්ස් ඔහ්, නෑ, සමාවෙන්න, මම අදහස් කළේ එහි වස්තු ආරම්භක අනුවාදයයි. new Book { Author = { Age = 45 } };අභ්‍යන්තර ආරම්භය පවා කරන්නේ කෙසේද ... අභ්‍යන්තර ආරම්භය කවදා හෝ ක්‍රියාත්මක වන තත්වයක් ගැන මට සිතිය නොහැකිය, නමුත් එය සම්පාදනය කර ඉන්ටෙලිසෙන්ස් ක්‍රියා කරයි ... ව්‍යුහයන් සඳහා නොවේද?

314

NullReference ව්‍යතිරේකය - දෘශ්‍ය මූලික

මෙම NullReference Exceptionසඳහා දෘශ්ය මූලික දී එක් වෙනස් නැත C # . සියල්ලට පසු, ඔවුන් දෙදෙනාම වාර්තා කරන්නේ .NET රාමුවේ අර්ථ දක්වා ඇති එකම ව්‍යතිරේකය ඔවුන් දෙදෙනාම භාවිතා කරන බවයි. දෘශ්‍ය මුලිකාංගයට අනන්‍ය වූ හේතු දුර්ලභ ය (සමහර විට එකක් පමණි).

මෙම පිළිතුර දෘශ්‍ය මූලික යෙදුම්, වාක්‍ය ඛණ්ඩය සහ සන්දර්භය භාවිතා කරයි. භාවිතා කරන උදාහරණ අතීත ස්ටැක් පිටාර ගැලීම් ප්‍රශ්න විශාල ගණනකින් පැමිණේ. මෙය භාවිතා කර අදාළ වන්නේ උපරිම ආකාරයේ බොහෝ විට තනතුරු දක්නට අවස්ථාවන්. අවශ්‍ය අය සඳහා තව ටිකක් පැහැදිලි කිරීමක් සපයනු ලැබේ. ඔබේ සමාන උදාහරණයක් වේ ඉතා ඉඩ මෙතන ලැයිස්තුගත.

සටහන:

  1. මෙය සංකල්ප මත පදනම් වූවකි: ඔබේ ව්‍යාපෘතියට ඇලවීම සඳහා කේතයක් නොමැත. NullReferenceException(NRE) ඇතිවීමට හේතුව , එය සොයා ගන්නේ කෙසේද, එය නිවැරදි කරන්නේ කෙසේද සහ එය වළක්වා ගන්නේ කෙසේද යන්න තේරුම් ගැනීමට ඔබට උදව් කිරීමට අදහස් කෙරේ . NRE බොහෝ ආකාරවලින් සිදුවිය හැකි බැවින් මෙය ඔබගේ එකම හමුවීම විය නොහැක.
  2. උදාහරණ (Stack Overflow පෝස්ට් වලින්) සෑම විටම යමක් කිරීමට හොඳම ක්‍රමය පෙන්වන්නේ නැත.
  3. සාමාන්යයෙන්, සරලම පිළියම භාවිතා වේ.

මූලික අර්ථය

"වස්තුව නිදසුනකට සකසා නැත" යන පණිවිඩයෙන් අදහස් කරන්නේ ඔබ ආරම්භ කර නොමැති වස්තුවක් භාවිතා කිරීමට උත්සාහ කරන බවයි. මෙය මෙයින් එකක් දක්වා උනු වේ:

  • ඔබේ කේතය වස්තු විචල්‍යයක් ප්‍රකාශයට පත් කළ නමුත් එය එය ආරම්භ කළේ නැත (නිදසුනක් සාදන්න හෝ එය ' ක්ෂණිකව ' කරන්න)
  • ඔබේ කේතය යම් වස්තුවක් ආරම්භ කරයි යැයි උපකල්පනය කළ දෙයක් නැත
  • වෙනත් කේත තවමත් භාවිතයේ පවතින වස්තුවක් අකාලයේ අවලංගු කිරීමට ඉඩ ඇත

හේතුව සොයා ගැනීම

ගැටළුව වස්තු යොමු කිරීමක් වන බැවින් Nothing, පිළිතුර වන්නේ ඒවා පරීක්ෂා කර ඒවා කුමන එකක් දැයි සොයා බැලීමයි. එය ආරම්භ නොකිරීමට හේතුව තීරණය කරන්න. විවිධ විචල්‍යයන් මත මූසිකය රඳවා තබා ගන්න. විෂුවල් ස්ටුඩියෝ (වීඑස්) ඒවායේ අගයන් පෙන්වනු ඇත - වැරදිකරු වනු ඇත Nothing.

IDE නිදොස්කරණය සංදර්ශකය

අදාළ කේතයෙන් ඔබ උත්සාහ කරන්න / අල්ලා ගන්න බ්ලොක් ඉවත් කළ යුතුය, විශේෂයෙන් Catch block හි කිසිවක් නොමැති තැන. මෙය ඔබේ කේතය වස්තුවක් භාවිතා කිරීමට උත්සාහ කරන විට එය බිඳ වැටීමට හේතු වේ Nothing. මෙය ඔබට අවශ්‍ය වන්නේ එය ගැටලුවේ නිශ්චිත ස්ථානය හදුනා ගන්නා අතර එයට හේතු වන වස්තුව හඳුනා ගැනීමට ඔබට ඉඩ සලසයි.

MsgBoxදුම්රිය අල්ලා දී ප්රදර්ශනය කරන Error while...පොඩි උපකාරයක් වනු ඇත. මෙම ක්‍රමය ඉතා නරක ස්ටැක් පිටාර ගැලීමේ ප්‍රශ්න වලට ද මග පාදයි , මන්ද ඔබට සත්‍ය ව්‍යතිරේකය, සම්බන්ධ වස්තුව හෝ එය සිදු වන කේත රේඛාව පවා විස්තර කළ නොහැක.

ඔබ ද භාවිතා කළ හැකිය Locals Window( > වාසීන් - -> වින්ඩෝස් ඩිබග් ඔබගේ වස්තූන් පරීක්ෂා කිරීමට).

ගැටලුව කුමක්ද සහ කොතැනදැයි ඔබ දැනගත් පසු, එය නව ප්‍රශ්නයක් පළ කිරීමට වඩා පහසුවෙන් විසඳා ගැනීමට පහසුය.

මෙයද බලන්න:

උදාහරණ සහ පිළියම්

පන්ති වස්තු / අවස්ථාවක් නිර්මාණය කිරීම

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

ගැටළුව වන්නේ DimCashRegister වස්තුවක් නිර්මාණය නොකිරීමයි ; එය ප්‍රකාශ කරන්නේ 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.

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

සටහන: VS 2010 සිට, දේශීය අරා වචනයක් භාවිතා කරමින් ආරම්භ කරන විට Option Infer, As <Type>සහ Newමූලද්‍රව්‍ය විකල්ප වේ:

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

පවරා ඇති දත්ත වලින් දත්ත වර්ගය සහ අරාවෙහි ප්‍රමාණය අනුමාන කෙරේ. පංති / මොඩියුල මට්ටමේ ප්‍රකාශ As <Type>සමඟ තවමත් අවශ්‍ය වන්නේ Option Strict:

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

උදාහරණය: පන්ති වස්තු පෙළ

Dim arrFoo(5) As Foo

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

අරාව නිර්මාණය කර ඇත, නමුත් එහි ඇති Fooවස්තූන් එසේ නොවේ.

පිළියමක්

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

List(Of T)වලංගු වස්තුවක් නොමැතිව මූලද්‍රව්‍යයක් තිබීම කැමැත්තක් භාවිතා කිරීම තරමක් අපහසු වනු ඇත:

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

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

වැඩි විස්තර සඳහා බලන්න:


ලැයිස්තු සහ එකතු

.NET එකතු කිරීම් (ඒවායින් වර්ග බොහොමයක් ඇත - ලැයිස්තු, ශබ්ද කෝෂය, ආදිය) ද ක්ෂණිකව හෝ නිර්මාණය කළ යුතුය.

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

එකම හේතුව නිසා ඔබට එකම ව්‍යතිරේකය ලැබෙනු ඇත - myListප්‍රකාශයට පත් කරන ලදි, නමුත් කිසිදු අවස්ථාවක් නිර්මාණය නොවීය. පිළියම එක හා සමානයි:

myList = New List(Of String)

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

පොදු අධීක්ෂණයක් යනු එකතුවක් භාවිතා කරන පන්තියකි Type:

Public Class Foo
    Private barList As List(Of Bar)

    Friend Function BarCount As Integer
        Return barList.Count
    End Function

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

එක්කෝ ක්‍රියා පටිපාටියේ ප්‍රති N ලයක් ලෙස එන්.ආර්.ඊ එකක් ලැබෙනු ඇත barList. නිදසුනක් Fooනිර්මාණය කිරීමෙන් අභ්‍යන්තරයේ නිදසුනක් ද නිර්මාණය නොවේ barList. ඉදිකිරීම්කරු තුළ මෙය කිරීමට අදහස් කර ඇත:

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

පෙර මෙන්, මෙය වැරදිය:

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

වැඩි විස්තර සඳහා List(Of T)පංතිය බලන්න .


දත්ත සපයන්නාගේ වස්තු

බොහෝ වස්තූන් ඇති විය හැකි බැවින්, දත්ත සමුදායන් තෑගි සමඟ NullReference සඳහා බොහෝ අවස්ථාවන් වැඩ ( Command, Connection, Transaction, Dataset, DataTable, DataRows....) භාවිතා එකවර. සටහන: ඔබ භාවිතා කරන්නේ කුමන දත්ත සැපයුම්කරුද යන්න ගැටළුවක් නොවේ - MySQL, SQL Server, OleDB, ආදිය - සංකල්ප එක හා සමානයි.

උදාහරණ 1

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

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

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

පෙර මෙන්, dsදත්ත සමුදාය වස්තුව ප්‍රකාශයට පත් කළ නමුත් නිදසුනක් කිසි විටෙකත් නිර්මාණය නොවීය. මෙම DataAdapterදැනට පවතින පුරවන්නේ DataSet, එකක් නිර්මාණය නොවේ. මෙම අවස්ථාවේදී, dsදේශීය විචල්‍යයක් බැවින්, මෙය සිදුවිය හැකි බවට IDE ඔබට අනතුරු අඟවයි :

img

මොඩියුලය / පන්ති මට්ටමේ විචල්‍යයක් ලෙස ප්‍රකාශයට පත් කළ විට මෙන් con, සම්පාදකයාට වස්තුව නිර්මාණය කර ඇත්තේ උඩු යටිකුරු ක්‍රියාපටිපාටියකින් දැයි දැනගත නොහැක. අනතුරු ඇඟවීම් නොසලකා හරින්න එපා.

පිළියමක්

Dim ds As New DataSet

උදාහරණ 2

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

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

අක්ෂර වින්‍යාසය මෙහි ගැටළුවක්: Employeesඑදිරිව Employee. DataTable"සේවකයා" ලෙස නම් කර නොමැත , එබැවින් NullReferenceExceptionප්‍රති access ල එයට ප්‍රවේශ වීමට උත්සාහ කරයි. තවත් විභව ගැටළුවක් වන්නේ ItemsSQL හි WHERE වගන්තියක් ඇතුළත් වන විට එසේ නොවිය හැකි යැයි උපකල්පනය කිරීමයි.

පිළියමක්

මෙය එක් වගුවක් භාවිතා කරන බැවින්, භාවිතා Tables(0)කිරීමෙන් අක්ෂර වින්‍යාස දෝෂ මඟ හැරෙනු ඇත. පරීක්ෂා කිරීම Rows.Countද උපකාරී වේ:

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

FillRowsපරීක්ෂා කළ හැකි බලපෑමට ලක්වූ සංඛ්‍යාව ආපසු ලබා දෙන ශ්‍රිතයකි :

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ඇත, නමුත් එය SQL හෝ දත්ත සමුදා වගුවෙන් නම් විග්‍රහ නොකරයි. එහි ds.Tables("TICKET_RESERVATION")ප්‍රති As ලයක් ලෙස නොපවතින වගුවක් සඳහන් කරයි.

මෙම පිළියමක් දර්ශකය විසින් මේසය අදාල, එකම ය:

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

ඩේටා ටේබල් පංතියද බලන්න .


වස්තු මාර්ග / කැදැල්ල

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

මෙම කේතය පමණක් පරීක්ෂා කෙරේ Itemsදෙකම අතර myFooසහ Barද කිසිවක් විය හැක. මෙම පිළියමක් වරකට වස්තූන් එක් සමස්ත දාම හෝ මාර්ගය පරීක්ෂා කිරීමට ය:

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

AndAlsoවැදගත්. පළමු Falseකොන්දේසිය හමු වූ පසු පසුව පරීක්ෂණ සිදු නොකෙරේ . මෙම අවස්ථාවක, ඇගයීම කේතය ආරක්ෂිතව වස්තුව (ව) එක් 'මට්ටමේ' බවට 'සරඹ' ඉඩ myFoo.Barපසු (සහ නම්) පමණක් myFooවලංගු වීමට අදිටන් කරගෙන ඇත. සංකීර්ණ වස්තු කේතනය කිරීමේදී වස්තු දාම හෝ මාර්ග තරමක් දිගු විය හැක:

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

nullවස්තුවක 'පහළට' කිසිවක් සඳහන් කළ නොහැක . පාලනයටද මෙය අදාළ වේ:

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

මෙන්න, myWebBrowserහෝ Documentකිසිවක් formfld1විය නොහැක හෝ මූලද්රව්ය නොපවතිනු ඇත.


UI පාලනයන්

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)

වෙනත් දේ අතර, පරිශීලකයා විසින් UI පාලක එකක් හෝ වැඩි ගණනක් තුළ යමක් තෝරාගෙන නොමැති බව මෙම කේතය අපේක්ෂා නොකරයි. ListBox1.SelectedItemකරනවා වෙන්න පුළුවන් Nothing, ඒ නිසා ListBox1.SelectedItem.ToStringයම් NRE හේතු වනු ඇත.

පිළියමක්

දත්ත භාවිතා කිරීමට පෙර එය වලංගු කරන්න (එසේම Option StrictSQL පරාමිතීන් භාවිතා කරන්න ):

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

NRE ලබා ගැනීම සඳහා මෙය තරමක් පොදු ක්‍රමයකි. C # හි, එය කේතනය කර ඇති ආකාරය මත පදනම්ව, IDE විසින් Controlsවර්තමාන සන්දර්භය තුළ නොපවතින බව වාර්තා කරයි , නැතහොත් "ස්ථිතික නොවන සාමාජිකයෙකු සඳහන් කළ නොහැක". ඉතින්, යම් දුරකට, මෙය VB පමණක් වන තත්වයකි. එය අසාර්ථක කඳුරැල්ලකට හේතු විය හැකි නිසා එය ද සංකීර්ණ ය.

අරා සහ එකතු කිරීම් මේ ආකාරයෙන් ආරම්භ කළ නොහැක. මෙම ආරම්භක කේතය ඉදිකිරීම්කරු විසින් නිර්මාණය කිරීමට පෙරForm හෝ Controls. ප්රතිඵලයක් වශයෙන්:

  • ලැයිස්තු සහ එකතු කිරීම හිස් වනු ඇත
  • අරාවෙහි කිසිවක් නොමැති අංග පහක් අඩංගු වේ
  • මෙම somevarකිසිවක් ඇති නොවන නිසා පැවරුම වහාම NRE හේතු වනු ඇත .Textදේපල

අරාවෙහි මූලද්‍රව්‍යයන් පසුව යොමු කිරීමෙන් NRE එකක් ලැබෙනු ඇත. Form_Loadඅමුතු දෝෂයක් හේතුවෙන් ඔබ මෙය කරන්නේ නම් , එය සිදු වූ විට IDE විසින් ව්‍යතිරේකය වාර්තා නොකරනු ඇත. ඔබේ කේතය අරාව භාවිතා කිරීමට උත්සාහ කරන විට ව්‍යතිරේකය පසුව උත්පතන වේ. මෙම "නිහ silent ව්යතිරේකය" මෙම ලිපියේ සවිස්තරව දක්වා ඇත . අපගේ අරමුණු සඳහා, ප්‍රධාන දෙය නම්, පෝරමයක් ( Sub Newහෝ Form Loadසිදුවීමක්) නිර්මාණය කිරීමේදී යම් ව්‍යසනකාරී දෙයක් සිදු වූ විට , ව්‍යතිරේකයන් වාර්තා නොවීමට ඉඩ ඇති විට, කේතය ක්‍රියා පටිපාටියෙන් ඉවත් වී පෝරමය පෙන්වයි.

ඔබගේ Sub Newහෝ Form Loadසිද්ධියේ වෙනත් කිසිදු කේතයක් NRE පසු ක්‍රියාත්මක නොවන බැවින්, තවත් බොහෝ දේ ආරම්භ නොකර තබා ගත හැකිය.

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

අරාව කේතය තවමත් වනාන්තරයෙන් පිටත නොතිබිය හැකිය. බහාලුම් පාලනයක (a GroupBoxහෝ වැනි Panel) ඕනෑම පාලනයක් සොයාගත නොහැක Me.Controls; ඒවා එම මණ්ඩලයේ හෝ සමූහ බොක්ස් හි පාලන එකතුවෙහි ඇත. පාලක නාමය අක්ෂර වින්‍යාසය සහිත විට පාලනයක් ආපසු ලබා නොදෙනු ඇත ( "TeStBox2"). එවැනි අවස්ථාවන්හිදී, Nothingනැවත එම අරාවෙහි මූලද්‍රව්‍යයන් තුළ ගබඩා වනු ඇති අතර ඔබ එය යොමු කිරීමට උත්සාහ කරන විට NRE ප්‍රති result ලයක් වනු ඇත.

ඔබ සොයන දේ ඔබ දන්නා බැවින් මේවා දැන් සොයා ගැනීම පහසු විය යුතුය: වීඑස් ඔබේ මාර්ගවල දෝෂය පෙන්වයි

"බොත්තම් 2" වාසය කරන්නේ a 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ප්‍රති result ලයක් විය හැකිය ' යනුවෙන් IDE ඔබට අනතුරු අඟවන අවස්ථාවකි . ඔබ වෙනුවට, මෙම අනතුරු ඇඟවීම යටපත් කළ හැකිය Exit Functionසමග Return Nothing, නමුත් එම ගැටලුව විසඳන්නේ නැහැ. ප්‍රතිලාභයක් භාවිතා කිරීමට උත්සාහ කරන ඕනෑම දෙයක් someCondition = FalseNRE වලට හේතු වේ:

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' ට පසුව) එහි ප්‍රති a ලය ව්‍යතිරේකයකි .ExecuteReader. Catchකිසිවක් නොකළ පසු , Finallyපිරිසිදු කිරීම සිදු කිරීමට උත්සාහ කරයි, නමුත් ඔබට Closeශුන්‍ය DataReaderවස්තුවක් කළ නොහැකි බැවින් , නවතම ප්‍රති .ල NullReferenceException.

හිස් Catchකොටස යනු යක්ෂයාගේ ක්‍රීඩා පිටියයි. ඔහු Finallyබ්ලොක් එකට එන්.ආර්.ඊ ලබා ගන්නේ ඇයිද යන්න මෙම OP අවුල් විය . වෙනත් අවස්ථාවන්හිදී, හිස් Catchවීමක් නිසා තවත් බොහෝ දේ පහළට පහළට පිදුරු ගෑමට ඉඩ ඇති අතර ගැටළුව සඳහා වැරදි ස්ථානයේ වැරදි දේ දෙස බැලීමට ඔබට කාලය ගත කළ හැකිය. (ඉහත විස්තර කර ඇති "නිහ silent ව්‍යතිරේකය" එකම විනෝදාස්වාද වටිනාකමක් ලබා දෙයි.)

පිළියමක්

හිස් උත්සාහ කරන්න / ඇල්ලීමේ කුට්ටි භාවිතා නොකරන්න - කේත බිඳවැටීමට ඉඩ දෙන්න එවිට ඔබට අ) හේතුව හඳුනා ගැනීමට ආ) ස්ථානය හඳුනාගෙන ඇ) නිසි පිළියමක් යොදන්න. උත්සාහ කරන්න / අල්ලා ගන්න කුට්ටි ඒවා නිවැරදි කිරීමට අද්විතීය සුදුසුකම් ඇති පුද්ගලයාගෙන් ව්‍යතිරේකයන් සැඟවීමට අදහස් නොකෙරේ - සංවර්ධකයා.


DBNull කිසිවක් නොවේ

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

මෙම IsDBNullනම්, එවැනි කියාකාරීත්වය පිළිබඳ පරීක්ෂණය කිරීම සඳහා භාවිතා වේ අගය සමාන System.DBNull: MSDN හි සිට:

System.DBNull අගය පෙන්නුම් කරන්නේ වස්තුව අතුරුදහන් වූ හෝ නොපවතින දත්ත නියෝජනය කරන බවයි. DBNull යනු කිසිවක් හා සමාන නොවේ, එයින් පෙන්නුම් කරන්නේ විචල්‍යයක් තවමත් ආරම්භ කර නොමැති බවයි.

පිළියමක්

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

පෙර මෙන්, ඔබට කිසිවක් සඳහා පරීක්ෂා කළ හැකිය, පසුව නිශ්චිත අගයක් සඳහා:

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

උදාහරණ 2

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

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

FirstOrDefaultපළමු අයිතමය හෝ පෙරනිමි අගය ලබා දෙයි, එය Nothingයොමු වර්ග සඳහා වන අතර කිසි විටෙකත් DBNull:

If getFoo IsNot Nothing Then...

පාලනයන්

Dim chk As CheckBox

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

නම්, එවැනි CheckBoxසමඟ chkNameහැකි සොයාගත නොහැකි විය (හෝ තුළ පවත්නා GroupBox), එසේ නම් chkකිසිම දෙයක් වනු ඇති අතර, ඕනෑම ධව උත්සාහ කරන ව්යතිරේකයක් හේතු වනු ඇත.

පිළියමක්

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

DataGridView

වරින් වර දැකිය හැකි කාරණා කිහිපයක් DGV සතුව ඇත:

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) NRE එකක් ඇති කරයි.

පිළියමක්

For/Eachලූපයක් භාවිතා කර IsNewRowදේපල පරීක්ෂා කරන්න එය අවසාන පේළියද යන්න තීරණය කරන්න. මෙය සත්‍යද නැද්ද යන්න AllowUserToAddRowsක්‍රියාත්මක වේ:

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

ඔබ For nලූපයක් භාවිතා කරන්නේ නම් , පේළි ගණන වෙනස් කරන්න හෝ සත්‍ය Exit Forවූ විට භාවිතා කරන්න IsNewRow.


My.Settings (StringCollection)

යම් යම් තත්වයන් යටතේ, අයිතමයක් භාවිතා කිරීමට උත්සාහ කිරීමෙන් ඔබ පළමු වරට එය භාවිතා කළ විට එය ශුන්‍ය My.Settingsයොමු කිරීමක් විය StringCollectionහැකිය. විසඳුම සමාන ය, නමුත් එතරම් පැහැදිලි නැත. සලකා බලන්න:

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

VB ඔබ වෙනුවෙන් සැකසීම් කළමනාකරණය කරන බැවින්, එය එකතු කිරීම ආරම්භ කරනු ඇතැයි අපේක්ෂා කිරීම සාධාරණ ය. එය සිදුවනු ඇත, නමුත් ඔබ මීට පෙර එකතුවට ආරම්භක ප්‍රවේශයක් එකතු කර ඇත්නම් පමණි (සැකසුම් සංස්කාරකයේ). අයිතමයක් එකතු කළ විට එකතු කිරීම (පෙනෙන පරිදි) ආරම්භ කර ඇති බැවින්, එකතු Nothingකිරීමට සැකසුම් සංස්කාරකයේ අයිතම නොමැති විට එය පවතී .

පිළියමක්

Loadඅවශ්‍ය නම් / පෝරමයේ සිදුවීම් හසුරුවන්නාගේ සැකසුම් එකතුව ආරම්භ කරන්න :

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

සාමාන්‍යයෙන්, Settingsඑකතු කිරීම ආරම්භ කළ යුත්තේ යෙදුම ක්‍රියාත්මක වන පළමු අවස්ථාව පමණි. විකල්ප පිළියමක් නම් ව්‍යාපෘතිය -> සැකසීම් | හි ඔබේ එකතුවට ආරම්භක අගයක් එකතු කිරීමයි FooBars , ව්‍යාපෘතිය සුරකින්න, පසුව ව්‍යාජ අගය ඉවත් කරන්න.


ප්‍රධාන කරුණු

ඔබට බොහෝ විට Newක්‍රියාකරු අමතක වී ඇත .

හෝ

ආරම්භක වස්තුවක් ඔබේ කේතයට ආපසු ලබා දීම සඳහා ඔබ දෝෂ සහිත ලෙස ක්‍රියා කරනු ඇතැයි උපකල්පනය කළ දෙයක් නැත.

සම්පාදක අනතුරු ඇඟවීම් නොසලකා හරින්න (කවදාවත්) සහ Option Strict On(සැමවිටම) භාවිතා කරන්න .


MSDN NullReference ව්‍යතිරේකය


226

තවත් අවස්ථාවක් නම් ඔබ ශුන්‍ය වස්තුවක් වටිනාකමට දැමූ විටය . උදාහරණයක් ලෙස, පහත කේතය:

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

එය NullReferenceExceptionරංගන ශිල්පීන් මතට විසි කරනු ඇත. ඉහත නියැදියෙන් එය පැහැදිලිව පෙනේ, නමුත් මෙය ඔබට අයිති නැති කේතයකින් ශුන්‍ය වස්තුව ආපසු ලබා දී ඇති වඩාත් “ප්‍රමාද බන්ධන” සංකීර්ණ අවස්ථා වලදී සිදුවිය හැකි අතර වාත්තු කිරීම සමහර ස්වයංක්‍රීය පද්ධතියකින් ජනනය වේ.

කැලැන්ඩර පාලනය සමඟ ඇති මෙම සරල ASP.NET බන්ධන කොටස මෙයට එක් නිදසුනකි:

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

මෙන්න, SelectedDateසැබවින්ම දේපල වේ - ක DateTimeවර්ගය - පිළිබඳ Calendarවෙබ් පාලන වර්ගය, හා බන්ධන හොඳින් යමක් ශූන්ය ආපසු විය. ව්‍යංග ASP.NET උත්පාදක යන්ත්රය ඉහත වාත්තු කේතයට සමාන කේත කැබැල්ලක් නිර්මාණය කරයි. මෙය NullReferenceExceptionහඳුනා ගැනීමට තරමක් අපහසු කාරණයක් මතු කරනු ඇත , මන්ද එය ASP.NET ජනනය කරන ලද කේතයක පිහිටා ඇති බැවින් එය හොඳින් සම්පාදනය කරයි ...


7
නියම ඇල්ලීම. වළක්වා ගත හැකි එක්-ලයිනර් ක්‍රමයක්:DateTime x = (DateTime) o as DateTime? ?? defaultValue;
සර්ජ් ෂුල්ට්ස්

160

එහි අර්ථය වන්නේ ප්‍රශ්නයේ විචල්‍යය කිසිවක් පෙන්වා නැති බවයි. මට මෙය එසේ ජනනය කළ හැකිය:

SqlConnection connection = null;
connection.Open();

ඒක තමයි මම විචල්ය ප්රකාශ කර ඇත අතර, "නිසා දෝෂ විසි ඇත connection", එය කිසිවක් පෙන්වා නැහැ. මම සාමාජිකයා " Open" ලෙස ඇමතීමට උත්සාහ කරන විට , එය විසඳීමට කිසිදු සඳහනක් නොමැති අතර එය දෝෂය විසි කරයි.

මෙම දෝෂය වළක්වා ගැනීම සඳහා:

  1. ඔබේ වස්තූන් සමඟ කිසිවක් කිරීමට උත්සාහ කිරීමට පෙර සෑම විටම ඒවා ආරම්භ කරන්න.
  2. වස්තුව ශුන්‍ය දැයි ඔබට විශ්වාස නැත්නම්, එය පරීක්ෂා කරන්න object == null.

ජෙට් බ්‍රේන්ස් හි නැවත පිරවීමේ මෙවලම මඟින් ඔබේ කේතයේ ඇති සෑම ස්ථානයක්ම ශුන්‍ය යොමු දෝෂයක් ඇතිවීමේ හැකියාව හඳුනාගනු ඇත. මෙම දෝෂය දෝෂ වල අංක එකේ ප්‍රභවය වන IMHO වේ.


3
ජෙට් බ්‍රේන්ස් හි නැවත පිරවීමේ මෙවලම ඔබගේ කේතයේ ඇති සෑම ස්ථානයක්ම ශුන්‍ය යොමු දෝෂයක් ඇති බව හඳුනා ගනී. මෙය වැරදිය. එම හඳුනා ගැනීමකින් තොරව මට විසඳුමක් ඇත, නමුත් කේතය විටින් විට ව්‍යතිරේකයට හේතු වේ. බහුවිධ කියවීම සම්බන්ධ වූ විට එය ඉඳහිට හඳුනාගත නොහැකි යැයි මම සැක කරමි, නමුත් මගේ දෝෂයේ පිහිටීම තවමත් හඳුනාගෙන නොමැති නිසා මට තවදුරටත් අදහස් දැක්විය නොහැක.
j riv

NullReferenceException usign HttpContext.Current.Responce.Clear () හි එන විට එය විසඳන්නේ කෙසේද? ඉහත කිසිදු විසඳුමකින් එය විසඳෙන්නේ නැත. මක්නිසාද යත්, එහි වස්තු වස්තුව වන HttpContext නිර්මාණය කිරීමේදී දෝෂයක් ඇතිවිය හැකි නිසා "අධි බර විභේදනය අසමත් වීම නිසා ප්‍රවේශ විය හැකි 'නව' මෙම තර්ක ගණන පිළිගන්නේ නැත.
සනී සන්දීප්

158

එයින් අදහස් වන්නේ ඔබේ කේතය ශුන්‍ය ලෙස සකසා ඇති වස්තු යොමු විචල්‍යයක් භාවිතා කර ඇති බවයි (එනම් එය සත්‍ය වස්තු අවස්ථාවක් සඳහන් නොකළේ).

දෝෂය වලක්වා ගැනීම සඳහා, භාවිතා කිරීමට පෙර ශුන්‍ය විය හැකි වස්තු ශුන්‍ය සඳහා පරීක්ෂා කළ යුතුය.

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

96

තත්වය කුමක් වුවත්, හේතුව සැමවිටම .NET හි සමාන බව මතක තබා ගන්න:

ඔබ අගය වේ, සමුද්දේශ විචල්ය භාවිත කිරීමට උත්සාහ කරන Nothing/ null. අගය Nothing/ nullවිමර්ශන විචල්‍යය සඳහා වන විට, එයින් අදහස් වන්නේ එය සංචයේ පවතින කිසියම් වස්තුවක නිදසුනක් වෙත යොමු කිරීමක් නොවන බවයි.

එක්කෝ ඔබ, විචල්ය යමක් පවරා නැහැ විචල්ය වෙත පවරා ඇති වටිනාකම පිළිබඳ උදාහරණයක් නිර්මාණය නෑ, හෝ ඔබ විචල්ය ඇති කිරීමට සමාන Nothing/ nullඅතින් නම්, හෝ ඔබ විසින් කිරීමට විචල්ය සකස් කරන කාර්යය නම් Nothing/ nullඔබ වෙනුවෙන්.


87

මෙම ව්‍යතිරේකය විසි කිරීම පිළිබඳ උදාහරණයක් නම්: ඔබ යමක් පරීක්ෂා කිරීමට උත්සාහ කරන විට එය ශුන්‍ය වේ.

උදාහරණයක් වශයෙන්:

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

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

.NET ධාවන වේලාව ඔබ ක්ෂණිකව නොකළ දෙයක්, එනම් ඉහත කේතය මත ක්‍රියාවක් කිරීමට උත්සාහ කරන විට NullReferenceException එකක් දමනු ඇත.

ArgumentNullException හා සැසඳීමේදී සාමාන්‍යයෙන් ආරක්ෂිත පියවරක් ලෙස විසි කරනු ලබන ක්‍රමවේදයක් මඟින් එය වෙත ලබා දෙන දෙය අහෝසි නොවන බව අපේක්ෂා කරයි.

වැඩි විස්තර C # NullReferenceException සහ Null පරාමිතියෙහි ඇත.


87

C # 8.0, 2019 යාවත්කාලීන කරන්න: අහෝසි කළ හැකි යොමු වර්ග

C # 8.0 හඳුන්වාදෙයි nullable යොමු වර්ග හා -nullable නොවන සමුද්දේශ වර්ග . එබැවින් NullReferenceException වළක්වා ගැනීම සඳහා පරීක්ෂා කළ යුත්තේ යොමු කළ හැකි යොමු වර්ග පමණි .


ඔබ විමර්ශන වර්ගයක් ආරම්භ කර නොමැති නම් සහ ඔබට එහි එක් ගුණාංගයක් සැකසීමට හෝ කියවීමට අවශ්‍ය නම්, එය NullReferenceException එකක් දමනු ඇත.

උදාහරණයක්:

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

විචල්‍යය ශුන්‍ය නොවේදැයි පරීක්ෂා කිරීමෙන් ඔබට මෙය වළක්වා ගත හැකිය:

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

NullReferenceException විසි කරන්නේ ඇයිද යන්න සම්පූර්ණයෙන් වටහා ගැනීම සඳහා, වටිනාකම් වර්ග සහ [විමර්ශන වර්ග] [3] අතර වෙනස දැන ගැනීම වැදගත්ය .

එබැවින්, ඔබ අගය වර්ග සමඟ කටයුතු කරන්නේ නම් , NullReferenceExceptions සිදුවිය නොහැක . විමර්ශන වර්ග සමඟ කටයුතු කිරීමේදී ඔබ සෝදිසියෙන් සිටිය යුතු වුවද !

නම යෝජනා කරන පරිදි යොමු යොමු වර්ග වලට පමණක් යොමු දැක්වීම් හෝ වචනාර්ථයෙන් කිසිවක් (හෝ 'ශුන්‍ය') වෙත යොමු කළ හැකිය. වටිනාකම් වර්ගවල සෑම විටම අගයක් අඩංගු වේ.

යොමු වර්ග (මේවා පරීක්ෂා කළ යුතුය):

  • ගතික
  • වස්තුව
  • නූල්

අගය වර්ග (ඔබට මේවා නොසලකා හැරිය හැක):

  • සංඛ්‍යාත්මක වර්ග
  • සමෝධානික වර්ග
  • පාවෙන ලක්ෂ්‍ය වර්ග
  • දශම
  • bool
  • පරිශීලක අර්ථ දක්වන ලද ව්‍යුහයන්

6
-1: ප්‍රශ්නය “NullReferenceException” යනු බැවින්, වටිනාකම් වර්ග අදාළ නොවේ.
ජෝන් සෝන්ඩර්ස්

21
ජෝන් සෝන්ඩර්ස්: මම එකඟ නොවෙමි. මෘදුකාංග සංවර්ධකයෙකු ලෙස අගය සහ යොමු වර්ග අතර වෙනස හඳුනා ගැනීමට හැකිවීම ඇත්තෙන්ම වැදගත් ය. නැතිනම් පූර්ණ සංඛ්‍යා ශුන්‍ය දැයි පිරික්සනු ඇත.
ෆේබියන් බිග්ලර්

5
ඇත්ත, මෙම ප්‍රශ්නයේ සන්දර්භය තුළ පමණක් නොවේ.
ජෝන් සෝන්ඩර්ස්

4
ඉඟියට ස්තූතියි. මම එය ටිකක් වැඩි දියුණු කර ඉහළින් උදාහරණයක් එක් කළෙමි. මම තවමත් යොමු සහ අගය වර්ග සඳහන් කිරීම ප්‍රයෝජනවත් යැයි සිතමි.
ෆේබියන් බිග්ලර්

5
මම හිතන්නේ ඔබ වෙනත් පිළිතුරුවලට ඇතුළත් කර නැති කිසිවක් එකතු කර නැති නිසා ප්‍රශ්නය යොමු යොමු වර්ගයක් පූර්ව උපකල්පනය කරයි.
ජෝන් සෝන්ඩර්ස්

78

NullReferenceExceptionsසිදුවිය හැකි තවත් අවස්ථාවක් නම් asක්‍රියාකරුගේ (වැරදි) භාවිතය :

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

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

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

මෙන්න, Bookසහ Carනොගැලපෙන වර්ග; a Carබවට පරිවර්තනය කළ නොහැක Book. මෙම වාත්තු කිරීම අසමත් වූ විට, asනැවත පැමිණේ null. මෙයින් mybookපසුව භාවිතා කිරීම a NullReferenceException.

පොදුවේ ගත් කල, ඔබ asපහත දැක්වෙන පරිදි වාත්තු කිරීමක් භාවිතා කළ යුතුය .

වර්ගය පරිවර්තනය සැමවිටම සාර්ථක වනු ඇතැයි ඔබ අපේක්ෂා කරන්නේ නම් (එනම්, වස්තුව කාලයට පෙර තිබිය යුතු දේ ඔබ දන්නවා), එවිට ඔබ වාත්තු භාවිතා කළ යුතුය:

ComicBook cb = (ComicBook)specificBook;

ඔබට වර්ගය ගැන සැකයක් නැත, නමුත් ඔබට එය විශේෂිත වර්ගයක් ලෙස භාවිතා කිරීමට උත්සාහ කිරීමට අවශ්‍ය නම්, භාවිතා කරන්න as:

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

2
විචල්‍යයක් අගුළු ඇරීමේදී මෙය බොහෝ දේ සිදුවිය හැකිය . මම UI මූලද්‍රව්‍යයේ වර්ගය වෙනස් කළ නමුත් කේතය පිටුපස යාවත්කාලීන කිරීමට අමතක වූ පසු සිදුවීම් හසුරුවන්නන් තුළ එය බොහෝ විට සිදුවන බව මට පෙනේ.
බ්‍රෙන්ඩන්

65

ඔබ භාවිතා කරන්නේ ශුන්‍ය අගය යොමුව අඩංගු වස්තුවයි. එබැවින් එය ශුන්‍ය ව්‍යතිරේකයක් ලබා දෙයි. උදාහරණයේ දී නූල් අගය ශුන්‍ය වන අතර එහි දිග පරීක්ෂා කිරීමේදී ව්‍යතිරේකය සිදුවිය.

උදාහරණයක්:

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

ව්‍යතිරේක දෝෂය:

පාලනය කළ නොහැකි ව්‍යතිරේකය:

System.NullReferenceException: වස්තු යොමු කිරීම වස්තුවක උදාහරණයකට සකසා නොමැත. වැඩසටහනේ දී. ප්‍රධාන ()


1
කෙතරම් ගැඹුරුද! මම කිසි විටෙකත් 'ශුන්‍ය' නියතය යොමු අගයක් ලෙස නොසැලකුවෙමි. ඉතින් C # "NullPointer" සාරාංශයක් කරන්නේ කෙසේද? B / c මා C ++ හි සිහිපත් කරන පරිදි, NPE ඇතිවිය හැක්කේ ආරම්භක නොවන දර්ශකයක් (එනම්, c # හි ref වර්ගය) අවලංගු කිරීමෙනි, එහි පෙරනිමි අගය එම ක්‍රියාවලියට වෙන් නොකරන ලද ලිපිනයක් වේ (බොහෝ අවස්ථාවන්හි මෙය 0, ස්වයංක්‍රීයව ආරම්භ කළ C ++ හි පසු සංස්කරණ වලදී, එය මෙහෙයුම් පද්ධතියට අයත් වන අතර එය සමඟ මියයනු ​​ඇත (නැතහොත් මෙහෙයුම් පද්ධතිය ඔබේ ක්‍රියාවලියට පහර දෙන සිගිල් අල්ලා ගන්න).
samis

64

අතර කුමන හේතු වේ NullReferenceExceptions හා ප්රවේශයන් / වැලැක්විමට හදන්න එවැනි හැර වෙනත් පිළිතුරු ආමන්ත්රණය කර ඇත, දේ බොහෝ වැඩසටහන්කරුවන් තවමත් උගත් නැහැ ස්වාධීනව කරන්නේ කෙසේ ද යන්න යි එකතුකරන්න සංවර්ධන තුළ එවැනි ව්යතිරේකයන්.

විෂුවල් ස්ටුඩියෝ හි මෙය සාමාන්‍යයෙන් දෘශ්‍ය ස්ටුඩියෝ නිදොස්කරණයට ස්තූතියි .


පළමුව, නිවැරදි දෝෂය හසු වන බවට වග බලා ගන්න - බලන්න VS2010 හි 'System.NullReferenceException' බිඳ දැමීමට මා ඉඩ දෙන්නේ කෙසේද? සටහන 1

ඉන්පසු නිදොස් කිරීම (F5) සමඟ ආරම්භ කරන්න හෝ ක්‍රියාත්මක කිරීමේ ක්‍රියාවලියට [VS නිදොස්කරණය] අමුණන්න . සමහර විට එය භාවිතා කිරීම ප්‍රයෝජනවත් විය හැකි අතර Debugger.Break, එය නිදොස්කරණය දියත් කිරීමට විමසනු ඇත.

දැන්, NullReferenceException විසි කළ විට (හෝ පාලනයකින් තොරව) නිදොස් කිරීම සිදු වූ රේඛාව මත නිදොස්කරණය නතර වනු ඇත (ඉහත සඳහන් කළ රීතිය මතකද?). සමහර විට දෝෂය පහසුවෙන් හඳුනාගත හැකිය.

නිදසුනක් ලෙස, පහත දැක්වෙන පේළියේ ව්‍යතිරේකයට හේතු විය හැකි එකම කේතය වන්නේ myStringශුන්‍ය ලෙස තක්සේරු කළහොත් පමණි . ඔරලෝසු කවුළුව දෙස බැලීමෙන් හෝ ක්ෂණික කවුළුවේ ප්‍රකාශන ධාවනය කිරීමෙන් මෙය සත්‍යාපනය කළ හැකිය .

var x = myString.Trim();

පහත දැක්වෙන වැනි වඩා දියුණු අවස්ථාවන්හිදී, ප්‍රකාශන str1ශුන්‍යද නැතිනම් ශුන්‍යද යන්න තීරණය කිරීම සඳහා ප්‍රකාශන පරීක්ෂා කිරීම සඳහා ඉහත ක්‍රම වලින් එකක් (වොච් හෝ ක්ෂණික වින්ඩෝස්) භාවිතා කිරීමට ඔබට අවශ්‍ය වේ str2.

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

වරක් එහිදී හැර විසි පිහිටා ඇත ඇත ඇත, එය හිස් අගයක් [වැරදි] හඳුන්වා දෙන ලදී එහිදී සොයා ගැනීමට සාමාන්යයෙන් හේතුව ආපස්සට අනවශ්ය ය -

ව්යතිරේකයේ හේතුව තේරුම් ගැනීමට අවශ්ය කාලය ගන්න. ශූන්‍ය ප්‍රකාශන සඳහා පරීක්ෂා කරන්න. එවැනි ශුන්‍ය ප්‍රකාශනවල ප්‍රති have ලයක් විය හැකි පෙර ප්‍රකාශන පරීක්ෂා කරන්න. බ්‍රේක්පොයින්ට් එකතු කර සුදුසු පරිදි වැඩසටහන හරහා පියවර තබන්න . නිදොස්කරණය භාවිතා කරන්න.


1 බ්‍රේක් ඔන් ත්‍රෝස් ඉතා ආක්‍රමණශීලී නම් සහ .NET හෝ තෙවන පාර්ශවීය පුස්තකාලයේ එන්පීඊ මත නිදොස්කරණය නතර වුවහොත්, අල්ලා ගත් ව්‍යතිරේකයන් සීමා කිරීම සඳහා බ්‍රේක් ඔන් පරිශීලක-හැන්ඩ්ල්ඩ් භාවිතා කළ හැකිය. මීට අමතරව, VS2012 Just My Code හඳුන්වා දෙන අතර එය සක්‍රීය කිරීමට මම නිර්දේශ කරමි.

ඔබ මගේ කේතය සක්‍රීය කර ඇති විට නිදොස්කරණය කරන්නේ නම්, හැසිරීම තරමක් වෙනස් වේ. Just My Code සක්‍රීය කර ඇති විට, නිදොස්කරණය මගේ කේතයෙන් පිටත විසි කරන සහ මගේ කේතය හරහා නොයන පළමු අවස්ථාව පොදු භාෂා ධාවන කාලය (CLR) නොසලකා හැරේ.


59

සයිමන් මොරියර් මෙම උදාහරණය දුන්නේය :

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

එහිදී යම් unboxing පරිවර්තනය (කාස්ට්) සිට object (හෝ පන්ති වලින් එකක් වන System.ValueTypeහෝ System.Enum, හෝ අතුරු මුහුණතේ ගණය සිට) වෙත අගය වර්ගය (හැර වෙනත් Nullable<>ම) ලබා දෙන අතර NullReferenceException.

අනෙක් දිශාවට, දී බොක්සිං පරිවර්තනය සිට එය Nullable<>ඇති HasValueසමාන false කිරීමට සැඳහුම වර්ගය, දෙන්න පුළුවන් nullනම් පසුව හේතු විය හැකි වන සඳහනක් NullReferenceException. හොඳම උදාහරණය:

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

සමහර විට බොක්සිං වෙනත් ආකාරයකින් සිදු වේ. උදාහරණයක් ලෙස මෙම සාමාන්‍ය නොවන දිගු කිරීමේ ක්‍රමය සමඟ:

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

පහත කේතය ගැටළු සහගත වනු ඇත:

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

මෙම අවස්ථා පැන නගින්නේ බොක්සිං Nullable<>අවස්ථා වලදී ධාවන කාලය භාවිතා කරන විශේෂ නීති නිසාය .


42

වස්තු රාමුව තුළ භාවිතා වන වස්තුව සඳහා පන්ති නාමය වෙබ් පෝරම කේත පිටුපස ගොනුවක් සඳහා පන්ති නාමයට සමාන වූ විට නඩුවක් එකතු කිරීම.

ඔබ සතුව Contact.aspx නම් වෙබ් පෝරමයක් ඇති අතර එහි කේත පිටුපස පන්තියේ සම්බන්ධතා ඇති අතර ඔබට සම්බන්ධතා නමක් ඇත.

ඔබ සන්දර්භය අමතන විට පහත කේතය NullReferenceException එකක් දමනු ඇත. SaveChanges ()

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

DataContext පන්තියේ සම්පූර්ණත්වය සඳහා

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

සහ සම්බන්ධතා වස්තු පන්තිය. සමහර විට වස්තු පංති අර්ධ පංති වන අතර එමඟින් ඔබට ඒවා වෙනත් ලිපිගොනු වලද ව්‍යාප්ත කළ හැකිය.

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

දෝෂය සිදුවන්නේ වස්තුව සහ කේත පිටුපස පන්තිය යන දෙකම එකම නාම අවකාශයක ඇති විටය. මෙය නිවැරදි කිරීම සඳහා, Contact.aspx සඳහා වස්තු පන්තිය හෝ කේත පිටුපස පන්තිය නැවත නම් කරන්න.

හේතුව මට තවමත් විශ්වාස නැත. නමුත් ඕනෑම වස්තු පන්තියක් System.Web.UI.Page දීර් extend කරන සෑම අවස්ථාවකම මෙම දෝෂය ඇතිවේ.

සාකච්ඡාව සඳහා DbContext.saveChanges () හි NullReferenceException බලන්න.


41

යමෙකුට මෙම ව්‍යතිරේකය ලැබිය හැකි තවත් පොදු සිද්ධියක් වන්නේ ඒකක පරීක්ෂණ අතරතුර පන්ති සමච්චලයට ලක් කිරීමයි. භාවිතා කරන සමච්චල් කිරීමේ රාමුව කුමක් වුවත්, පන්ති ධූරාවලියේ සියලු සුදුසු මට්ටම් නිසි ලෙස සමච්චලයට ලක්වන බවට ඔබ සහතික විය යුතුය. විශේෂයෙන්, HttpContextපරීක්ෂණය යටතේ ඇති කේතය මගින් සඳහන් කර ඇති සියලුම ගුණාංග සමච්චලයට ලක් කළ යුතුය.

තරමක් වාචික උදාහරණයක් සඳහා " අභිරුචි බලය පැවරීම පරීක්ෂා කිරීමේදී විසි කරන ලද NullReferenceException " බලන්න .


40

මෙයට පිළිතුරු දීමට මට වෙනස් ඉදිරිදර්ශනයක් ඇත. මේ ආකාරයේ පිළිතුරු "එය වළක්වා ගැනීමට මට වෙන කුමක් කළ හැකිද? "

විවිධ ස්ථර හරහා වැඩ කරන විට , උදාහරණයක් ලෙස MVC යෙදුමක, පාලකයෙකුට ව්‍යාපාර මෙහෙයුම් ඇමතීමට සේවාවන් අවශ්‍ය වේ. එවැනි අවස්ථා වලදී NullReferenceException වළක්වා ගැනීම සඳහා සේවාවන් ආරම්භ කිරීම සඳහා යැපුම් එන්නත් කන්ටේනරය භාවිතා කළ හැකිය . එබැවින් එයින් අදහස් වන්නේ ඔබ ශුන්‍යය පරීක්ෂා කිරීම ගැන කරදර විය යුතු නැති අතර පාලක වෙතින් සේවාවන් සෑම විටම ලබා ගත හැකි (සහ ආරම්භ කරන ලද) තනි තනි හෝ මූලාකෘතියක් ලෙසට ය.

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

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

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

6
-1: මෙය හසුරුවන්නේ එක් දර්ශනයක් පමණි - ආරම්භක නොවන පරායත්තතාවයන්. මෙය NullReferenceException සඳහා සුළුතර අවස්ථාවකි. බොහෝ අවස්ථාවන්හිදී වස්තූන් ක්‍රියා කරන ආකාරය පිළිබඳ සරල වරදවා වටහා ගැනීමකි. ඊළඟට බොහෝ විට සිදුවන්නේ සංවර්ධකයා විසින් වස්තුව ස්වයංක්‍රීයව ආරම්භ කරනු ඇතැයි උපකල්පනය කළ අවස්ථා ය.
ජෝන් සෝන්ඩර්ස්

NullReferenceException වළක්වා ගැනීම සඳහා පරායත්ත එන්නත් කිරීම සාමාන්‍යයෙන් භාවිතා නොවේ. ඔබ මෙහි පොදු සිදුවීමක් සොයාගෙන ඇතැයි මම විශ්වාස නොකරමි. ඕනෑම අවස්ථාවක, ඔබේ පිළිතුර stackoverflow.com/a/15232518/76337 ශෛලියට වඩා වැඩි ලෙස සංස්කරණය කළහොත් , මම පහත සඳහන් අගය ඉවත් කරමි.
ජෝන් සෝන්ඩර්ස්

38

"මම ඒ ගැන කුමක් කළ යුතුද" යන කාරණය සම්බන්ධයෙන් බොහෝ පිළිතුරු තිබිය හැකිය.

එවැනි දෝෂ තත්වයන් වැළැක්වීම පිළිබඳව වඩාත් "විධිමත්" මාර්ගය සංවර්ධනය අතර අදාළ කරන්නේ, කොන්ත්රාත් විසින් නිර්මාණය ඔබගේ කේතය දී. මෙම මාර්ගයෙන් ඔබ මාලාවක් පන්තියට අවශ්ය invariants , සහ / හෝ කාර්යය / ක්රමය පූර්ව කොන්දේසි හා postconditions සංවර්ධනය අතර, ඔබේ පද්ධතිය මත.

කෙටියෙන් කිවහොත්, පන්ති invariants සාමාන්ය භාවිතය උල්ලංඝනය වීම නොවන බව ඔබේ පන්තියේ සමහර සීමාවන් වනු ඇත (සහ ඒ නිසා, පන්ති බව සහතික නෑ අස්ථාවර දී ලබා). පූර්ව කොන්දේසි යනු ශ්‍රිතයකට / ක්‍රමයකට ආදානය ලෙස ලබා දී ඇති දත්ත යම් යම් සීමාවන් අනුගමනය කළ යුතු අතර ඒවා කිසි විටෙකත් උල්ලං late නය නොකළ යුතු අතර පශ්චාත් කොන්දේසි යන්නෙන් අදහස් වන්නේ ශ්‍රිතයක් / ක්‍රම ප්‍රතිදානයක් මඟින් කිසි විටෙකත් ඒවා උල්ලං without නය නොකර නැවත සකස් කළ යුතු බවයි. කොන්ත්රාත් කොන්දේසි යුතු නැහැ දෝෂය-නිදහස් වැඩසටහන ක්රියාත්මක තුළ උල්ලංඝණය කළ, ඒ නිසා කොන්ත්රාත් විසින් නිර්මාණය ප්රායෝගිකව දෝශනිරාකරණ වාර්ථා ආකාරයෙන්, ලබන අතර, පරීක්ෂා කෙරේ නිකුත් අක්රිය , සංවර්ධිත පද්ධතිය උපරිම කාර්යක්ෂමතාව.

මේ ආකාරයෙන්, NullReferenceExceptionනියම කර ඇති අවහිරතා උල්ලං of නය කිරීමේ ප්‍රති results ල වන අවස්ථා වළක්වා ගත හැකිය . නිදසුනක් ලෙස, ඔබ Xපන්තියක වස්තු දේපලක් භාවිතා කර පසුව එහි එක් ක්‍රමයක් භාවිතා කිරීමට උත්සාහ Xකර ශුන්‍ය අගයක් දරන්නේ නම්, මෙය මෙයට හේතු වනු ඇත NullReferenceException:

public X { get; set; }

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

නමුත් ඔබ "දේපල X කිසි විටෙකත් ශුන්‍ය අගයක් නොතිබිය යුතුය" යන්න ක්‍රමවේදය පූර්ව කොන්දේසියක් ලෙස සකසන්නේ නම්, ඔබට කලින් විස්තර කර ඇති තත්වය වළක්වා ගත හැකිය:

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

මෙම හේතුව නිසා .NET යෙදුම් සඳහා කේත කොන්ත්‍රාත් ව්‍යාපෘතිය පවතී.

විකල්පයක් ලෙස, කොන්ත්රාත්තුව අනුව සැලසුම් කිරීම ප්රකාශයන් භාවිතා කළ හැකිය .

යාවත්කාලීන කිරීම: බර්ට්‍රන්ඩ් මේයර් විසින් අයිෆල් ක්‍රමලේඛන භාෂාව නිර්මාණය කිරීම සම්බන්ධව මෙම යෙදුම භාවිතා කළ බව සඳහන් කිරීම වටී .


2
කිසිවෙකු සඳහන් නොකළ පරිදි මෙය එකතු කිරීමට මම සිතුවෙමි, එය ප්‍රවේශයක් ලෙස පවතින තාක් දුරට මගේ අභිප්‍රාය වූයේ මාතෘකාව පොහොසත් කිරීමයි.
නික් එල්.

2
මාතෘකාව පොහොසත් කිරීමට ස්තූතියි. ඔබගේ එකතු කිරීම පිළිබඳව මම මගේ මතය ඉදිරිපත් කර ඇත්තෙමි. දැන් අනෙක් අයටත් එසේ කළ හැකිය.
ජෝන් සෝන්ඩර්ස්

2
මෙය ඉහළ නරඹන ලද නූලක් බැවින් මාතෘකාවට මෙය වටිනා එකතු කිරීමක් යැයි මම සිතුවෙමි. කේත ගිවිසුම් ගැන මා මීට පෙර අසා ඇති අතර ඒවා භාවිතා කිරීම ගැන සලකා බැලීමට මෙය හොඳ මතක් කිරීමකි.
VoteCoffee

36

NullReferenceExceptionඅපි ශුන්‍ය වස්තුවක ගුණාංග වෙත ප්‍රවේශ වීමට උත්සාහ කරන විට හෝ නූල් අගයක් හිස් වූ විට අපි නූල් ක්‍රමවලට ප්‍රවේශ වීමට උත්සාහ කරන විට A විසි කරනු ලැබේ.

උදාහරණයක් වශයෙන්:

  1. හිස් නූලක නූල් ක්‍රමයක් ප්‍රවේශ වූ විට:

    string str = string.Empty;
    str.ToLower(); // throw null reference exception
  2. ශුන්‍ය වස්තුවක දේපලකට ප්‍රවේශ වූ විට:

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

2
මෙය වැරදිය. String.Empty.ToLower()ශුන්‍ය යොමු ව්‍යතිරේකයක් විසි නොකරනු ඇත. එය හිස් එකක් වුවද (එනම් "") සත්‍ය නූලක් නියෝජනය කරයි . මෙය ඉල්ලා ToLower()සිටීමට වස්තුවක් ඇති බැවින් , ශුන්‍ය යොමු ව්‍යතිරේකයක් එහි විසි කිරීම අර්ථවත් නොවේ.
ක්ජාර්ටන්

31

TL; DR:Html.Partial ඒ වෙනුවට භාවිතා කිරීමට උත්සාහ කරන්නRenderpage


Object reference not set to an instance of an objectදර්ශනයක් තුළ ආකෘතියක් යැවීමෙන් දර්ශනයක් ඉදිරිපත් කිරීමට උත්සාහ කරන විට මට ලැබුණේ මෙයයි:

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

නිදොස් කිරීම මගින් පෙන්නුම් කළේ මෙම ආකෘතිය MyOtherView තුළ ශුන්‍ය බවයි. මම එය වෙනස් කරන තුරු:

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

එය ක්‍රියාත්මක විය.

තව දුරටත්, මට Html.Partialආරම්භ කිරීමට අවශ්‍ය නොවූයේ, විෂුවල් ස්ටුඩියෝ සමහර විට දෝෂ සහිත පෙනුමක් ඇති රේඛා විසි Html.Partialකරන්නේ එය වෙනස් ආකාරයකින් සාදන ලද foreachලූපයක් තුළ නම්, එය ඇත්ත වශයෙන්ම දෝෂයක් නොවුනත් ය:

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

නමුත් මෙම "දෝෂය" සමඟ කිසිදු ගැටළුවක් නොමැතිව යෙදුම ක්රියාත්මක කිරීමට මට හැකි විය. foreachමේ ආකාරයට පෙනීම සඳහා ලූපයේ ව්‍යුහය වෙනස් කිරීමෙන් දෝෂයෙන් මිදීමට මට හැකි විය :

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

මට හැඟීමක් තිබුණත්, දෘශ්‍ය ස්ටුඩියෝ විසින් ඇම්පියර්සෑන්ඩ් සහ වරහන් වැරදි ලෙස කියවා තිබීම ඊට හේතුවයි.


ඔබට අවශ්‍ය වූයේ Html.Partialනැත@Html.Partial
ජෝන් සෝන්ඩර්ස්

තවද, ව්‍යතිරේකය විසි කළේ කුමන රේඛාවද, ඇයිද යන්න කරුණාකර පෙන්වන්න.
ජෝන් සෝන්ඩර්ස්

MyOtherView.cshtml හි දෝෂය ඇතිවිය, එය මා මෙහි ඇතුළත් නොකළේ, මොඩලය නිසියාකාරව යවා නොමැති නිසා (එය එසේ විය Null), එබැවින් දෝෂය මා මොඩලය යවන ආකාරය සමඟ බව මම දැන සිටියෙමි.
ට්‍රැවිස් හීටර්

22

ඔබට ඒ ගැන කුමක් කළ හැකිද?

ශුන්‍ය යොමු කිරීමක් යනු කුමක්ද සහ එය නිදොස් කරන්නේ කෙසේද යන්න පැහැදිලි කිරීම සඳහා මෙහි හොඳ පිළිතුරු රාශියක් ඇත. නමුත් ගැටළුව වළක්වා ගන්නේ කෙසේද යන්න හෝ අවම වශයෙන් අල්ලා ගැනීම පහසු කරන්නේ කෙසේද යන්න පිළිබඳ ඉතා අල්පය.

තර්ක පරීක්ෂා කරන්න

නිදසුනක් ලෙස, ක්‍රම මගින් විවිධ තර්ක පරික්‍ෂා කර ඒවා ශුන්‍ය දැයි බැලීමට හැකි ArgumentNullExceptionඅතර මෙම නිශ්චිත අරමුණ සඳහා පැහැදිලිවම නිර්මාණය කරන ලද ව්‍යතිරේකයකි.

ArgumentNullExceptionඉරට්ටේ සඳහා වන ඉදිකිරීම්කරු පරාමිතියේ නම සහ පණිවිඩයක් තර්ක ලෙස ගනී, එවිට ඔබට ගැටලුව කුමක්දැයි සංවර්ධකයාට හරියටම කිව හැකිය.

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

මෙවලම් භාවිතා කරන්න

උපකාර කළ හැකි පුස්තකාල කිහිපයක් ද තිබේ. උදාහරණයක් ලෙස "නැවත පිරවීම" මඟින් ඔබ කේත ලිවීමේදී අනතුරු ඇඟවීම් ලබා දිය හැකිය, විශේෂයෙන් ඔබ ඔවුන්ගේ ගුණාංගය භාවිතා කරන්නේ නම්: NotNullAttribute

"මයික්‍රොසොෆ්ට් කේත කොන්ත්‍රාත්තු" ඇත, එහිදී ඔබ සින්ටැක්ස් භාවිතා Contract.Requires(obj != null)කරන අතර එමඟින් ඔබට ධාවන කාලය සහ පරික්ෂා කිරීම සිදු කරයි: කේත කොන්ත්‍රාත්තු හඳුන්වා දීම .

"PostSharp" ද ඇත, එමඟින් ඔබට මෙවැනි ගුණාංග භාවිතා කිරීමට ඉඩ ලබා දේ:

public void DoSometing([NotNull] obj)

එය කිරීමෙන් සහ ඔබගේ ගොඩනැගීමේ ක්‍රියාවලියේ PostSharp කොටසක් බවට පත් කිරීමෙන් ධාවන වේලාවේදී අහෝසි වේදැයි objපරීක්ෂා කරනු ලැබේ. බලන්න: PostSharp null check

සරල කේත විසඳුම

නැතහොත් ඔබට සෑම විටම සරල පැරණි කේත භාවිතා කර ඔබේම ප්‍රවේශය කේත කළ හැකිය. උදාහරණයක් ලෙස මෙහි ඔබට ශූන්‍ය යොමු කිරීම් භාවිතා කළ හැකි ව්‍යුහයකි. එය එකම සංකල්පයකින් පසුව ආදර්ශනය කර ඇත Nullable<T>:

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

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

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

            _value = value;
        }
    }

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

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

Nullable<T>හරියටම ප්‍රතිවිරුද්ධ දෙය ඉටු කිරීමේ ඉලක්කය හැර - ඔබ භාවිතා නොකරන ආකාරයටම ඔබ බොහෝ සමාන භාවිතා කරනු ඇත null. මෙන්න උදාහරණ කිහිපයක්:

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

NotNull<T>ව්‍යංගයෙන් සහ ඉන් පිටතට දමනු ලබන Tබැවින් ඔබට එය අවශ්‍ය ඕනෑම තැනක භාවිතා කළ හැකිය. උදාහරණයක් ලෙස, ඔබට Personවස්තුවක් ගත හැකි ක්‍රමයකට යොමු කළ හැකිය NotNull<Person>:

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

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

ඉහත සඳහන් කළ හැකි පරිදි ඔබට Valueදේපල හරහා යටින් පවතින වටිනාකමට ප්‍රවේශ විය හැකිය . විකල්පයක් ලෙස, ඔබට පැහැදිලි හෝ ව්‍යංග වාත්තු භාවිතා කළ හැකිය, පහත ප්‍රතිලාභ අගය සමඟ උදාහරණයක් ඔබට දැක ගත හැකිය:

Person person = GetPerson();

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

නැතහොත් වාත්තු කිරීම මඟින් ක්‍රමය නැවත පැමිණෙන විට T(මෙම අවස්ථාවේ දී Person) ඔබට එය භාවිතා කළ හැකිය . උදාහරණයක් ලෙස, පහත කේතය ඉහත කේතයට කැමතියි:

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

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

දිගු කිරීම සමඟ ඒකාබද්ධ කරන්න

NotNull<T>දිගු කිරීමේ ක්‍රමයක් සමඟ ඒකාබද්ධ කරන්න, ඔබට ඊටත් වඩා තත්වයන් ආවරණය කළ හැකිය. දිගු කිරීමේ ක්‍රමය කෙබඳු විය හැකිද යන්න පිළිබඳ උදාහරණයක් මෙන්න:

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

        return @this;
    }
}

එය භාවිතා කළ හැකි ආකාරය පිළිබඳ උදාහරණයක් මෙහි දැක්වේ:

var person = GetPerson().NotNull();

GitHub

ඔබගේ යොමු කිරීම සඳහා මම ඉහත කේතය GitHub වෙතින් ලබා ගත හැකි අතර, ඔබට එය සොයාගත හැක්කේ:

https://github.com/luisperezphd/NotNull

අදාළ භාෂා විශේෂාංගය

සී # 6.0 විසින් "ශුන්‍ය-කොන්දේසි සහිත ක්‍රියාකරු" හඳුන්වා දෙන ලදී. මෙම අංගය සමඟ, ඔබට කැදැලි වස්තූන් යොමු කළ හැකි අතර ඒවායින් එකක් nullනම් සම්පූර්ණ ප්‍රකාශනය නැවත පැමිණේ null.

මෙය සමහර අවස්ථාවල ඔබ විසින් කළ යුතු ශුන්‍ය චෙක්පත් ගණන අඩු කරයි. වාක්‍ය ඛණ්ඩය යනු සෑම තිතකටම පෙර ප්‍රශ්නාර්ථ ලකුණක් තැබීමයි. උදාහරණයක් ලෙස පහත කේතය ගන්න:

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

එය දේපල countryවර්ගයක් Countryලෙස හැඳින්වෙන වස්තුවක් යැයි සිතන්න State. නම් country, State, County, හෝ Cityවේ nullනම් address will beශූන්ය . Therefore you only have to check whetherලිපිනය isnull`.

එය විශිෂ්ට ලක්ෂණයකි, නමුත් එය ඔබට අඩු තොරතුරු ලබා දෙයි. 4 න් කුමන ශුන්‍යද යන්න එය පැහැදිලි නොකරයි.

Nullable වැනි ගොඩනගා තිබේද?

C # සඳහා කදිම කෙටිමං ඇත Nullable<T>, එවැනි වර්ගයට පසුව ප්‍රශ්නාර්ථ ලකුණක් තැබීමෙන් ඔබට අහෝසි කළ හැකිය int?.

C # හි NotNull<T>ඉහත ව්‍යුහය හා සමාන කෙටිමං එකක් තිබේ නම් හොඳයි , සමහර විට විශ්මයජනක ලක්ෂ්‍යය (!) එවිට ඔබට එවැනි දෙයක් ලිවිය හැකිය : public void WriteName(Person! person).


2
කිසි විටෙකත් NullReferenceException විසි නොකරන්න
ජෝන් සෝන්ඩර්ස්

@ ජෝන් සෝන්ඩර්ස් මම එහෙම අහන්නේ ඇයි කියලා අහන්න? (බරපතල ලෙස එසේ වන්නේ ඇයි?)
ලුයිස් පෙරෙස්

2
NullReferenceException යන්න CLR විසින් විසි කිරීමට අදහස් කරයි. එයින් අදහස් වන්නේ ශුන්‍යයක් පිළිබඳ සඳහනක් සිදුවී ඇති බවයි. ඔබ මුලින් බුද්ධිමත්ව පරික්‍ෂා කිරීම හැර, ශුන්‍යයක් පිළිබඳ සඳහනක් සිදුවනු ඇතැයි එයින් අදහස් නොවේ.
ජෝන් සෝන්ඩර්ස්

එය ව්‍යාකූල වන්නේ කෙසේද යන්න පිළිබඳ ඔබේ අදහස මම දකිමි. මෙම උදාහරණය සඳහා මම එය සාමාන්‍ය ව්‍යතිරේකයකට සහ GitHub හි අභිරුචි ව්‍යතිරේකයකට යාවත්කාලීන කර ඇත.
ලුයිස් පෙරෙස්

එවැනි මූලික ප්‍රශ්නයකට විශිෂ්ට පිළිතුරක්. ඔබගේ කේතය අසමත් වන විට එය එතරම් නරක නැත. ඔබ විශ්වාස කරන වාණිජ තෙවන පාර්ශවීය පුස්තකාලයක් ඇතුළත සිට පැමිණෙන විට එය භයානක වන අතර පාරිභෝගික සහාය එය ගැටළුවට හේතු වන ඔබේ කේතය විය යුතු බව අවධාරනය කරයි. ඔබට එය සම්පුර්ණයෙන්ම විශ්වාස නැති අතර මුළු ව්‍යාපෘතියම නතර වීමට ඉඩ ඇත .. ඇත්ත වශයෙන්ම මෙය මගේ සොහොන් ගල සඳහා සුදුසු සාරාංශයක් වනු ඇතැයි මම සිතමි: "වස්තු සඳහනක් වස්තුවක උදාහරණයකට සකසා නැත."
ඩැරල් ලී

10

සිත්ගන්නා කරුණ නම්, මෙම පිටුවේ කිසිදු පිළිතුරක අද්දර අවස්ථා දෙක ගැන සඳහන් නොවේ, මම ඒවා එකතු කළහොත් කිසිවෙකු සිතන්නේ නැත:

එජ් නඩුව # 1: ශබ්දකෝෂයකට සමගාමී ප්‍රවේශය

.NET හි ඇති සාමාන්‍ය ශබ්දකෝෂ නූල්-ආරක්ෂිත නොවන අතර සමහර විට ඔබ සමගාමී නූල් දෙකකින් යතුරකට ප්‍රවේශ වීමට උත්සාහ NullReferenceකරන KeyNotFoundExceptionවිට ඒවා සමහර විට හෝ ඊටත් වඩා (නිතර නිතර) විසි කළ හැකිය . ව්යතිරේකය මෙම නඩුවේ තරමක් නොමඟ යවන සුළුය.

එජ් නඩුව # 2: අනාරක්ෂිත කේතය

කේතයක් NullReferenceExceptionමඟින් විසි කරනු ලැබුවහොත් unsafe, ඔබට ඔබේ දර්ශක විචල්‍යයන් දෙස බලා ඒවා IntPtr.Zeroහෝ වෙනත් දෙයක් පරීක්ෂා කරන්න. එය එකම දෙයයි ("ශුන්‍ය දර්ශක ව්‍යතිරේකය"), නමුත් අනාරක්ෂිත කේතයේ විචල්‍යයන් බොහෝ විට අගය වර්ග / අරා යනාදිය වෙතට දමනු ලැබේ. තවද ඔබ ඔබේ හිස බිත්තියට එබීමෙන් වටිනාකමක් ඇති වර්ගයක් මෙය විසි කරන්නේ කෙසේදැයි කල්පනා කරයි ව්යතිරේකය.

(අනාරක්ෂිත කේතයක් ඔබට අවශ්‍ය නම් මිස භාවිතා නොකිරීමට තවත් හේතුවක්)


5
ඔබේ ශබ්ද කෝෂයේ උදාහරණය අද්විතීය අවස්ථාවක් නොවේ. වස්තුව නූල් ආරක්ෂිත නොවේ නම්, බහු නූල් වලින් එය භාවිතා කිරීම අහඹු ප්‍රති .ල ලබා දෙයි. ඔබගේ අනාරක්ෂිත කේත උදාහරණය nullකුමන ආකාරයෙන් වෙනස් වේද?
ජෝන් සෝන්ඩර්ස්

10

C # 6 හි ශුන්‍ය-කොන්දේසි සහිත ක්‍රියාකරුවන් භාවිතා කර ඔබට NullReferenceException පිරිසිදු ආකාරයකින් සවි කළ හැකි අතර ශුන්‍ය චෙක්පත් හැසිරවීමට අඩු කේතයක් ලියන්න.

සාමාජික ප්‍රවේශයක් (?.) හෝ දර්ශක (? [) මෙහෙයුමක් කිරීමට පෙර එය ශුන්‍ය ලෙස පරීක්ෂා කිරීමට භාවිතා කරයි.

උදාහරණයක්

  var name = p?.Spouse?.FirstName;

සමාන වේ:

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

මෙහි ප්‍රති result ලය වනුයේ p ශුන්‍ය වූ විට හෝ p.Spouse ශුන්‍ය වූ විට නම ශුන්‍ය වනු ඇත.

එසේ නොමැතිනම් විචල්ය නාමයට p.Spouse.FirstName හි අගය පවරනු ලැබේ.

වැඩි විස්තර සඳහා: ශුන්‍ය-කොන්දේසි සහිත ක්‍රියාකරුවන්


9

"වස්තු යොමු කිරීම වස්තුවක නිදසුනකට සකසා නැත" යන දෝෂ රේඛාවේ සඳහන් වන්නේ ඔබ වස්තු යොමු කිරීම සඳහා නිදර්ශන වස්තුව පවරා නොමැති බවත් තවමත් ඔබ එම වස්තුවේ නිසි / ක්‍රම වෙත ප්‍රවේශ වන බවත් ය.

උදාහරණයක් ලෙස: ඔබට myClass නමින් පන්තියක් ඇති බවත් එහි එක් දේපල prop1 අඩංගු බවත් කියමු.

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

දැන් ඔබ පහත දැක්වෙන ආකාරයට වෙනත් පන්තියකට මෙම prop1 වෙත පිවිසෙමින් සිටී:

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

ඔබ භාවිතා කිරීමට උත්සාහ කරන පන්තියේ වස්තුවක් ක්ෂණිකව නොපවතින විට NullReferenceException හෝ වස්තු යොමු කිරීම වස්තුවක උදාහරණයකට සකසා නොමැත. උදාහරණයක් වශයෙන්:

ඔබට ශිෂ්‍යයා නමින් පන්තියක් ඇතැයි උපකල්පනය කරන්න.

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

දැන්, ඔබ ශිෂ්‍යයාගේ සම්පූර්ණ නම ලබා ගැනීමට උත්සාහ කරන වෙනත් පන්තියක් සලකා බලන්න.

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

ඉහත කේතයේ දැකිය හැකි පරිදි, ශිෂ්‍යයාගේ ප්‍රකාශය ශිෂ්‍ය වර්ගයෙහි විචල්‍යය පමණක් ප්‍රකාශ කරයි, මේ අවස්ථාවේදී ශිෂ්‍ය පන්තිය ක්ෂණිකව සිදු නොවන බව සලකන්න. එබැවින්, s.GetFullName () ප්‍රකාශය ක්‍රියාත්මක වූ විට, එය NullReferenceException විසි කරයි.


3

හොඳයි, සරල වචන වලින්:

ඔබ උත්සාහ කරන්නේ නිර්මාණය කර නැති හෝ දැනට මතකයේ නොමැති වස්තුවකට ප්‍රවේශ වීමට ය.

ඉතින් මෙය විසඳන්නේ කෙසේද:

  1. නිදොස්කරණය කර නිදොස්කරණය කිරීමට ඉඩ දෙන්න ... එය කෙලින්ම ඔබව කැඩී ඇති විචල්‍යයට ගෙන යනු ඇත ... දැන් ඔබේ කාර්යය වන්නේ මෙය සරලව නිවැරදි කිරීමයි .. නව යතුරු පදය සුදුසු ස්ථානයේ භාවිතා කිරීම.

  2. වස්තුව නොපවතින හෙයින් එය සමහර දත්ත සමුදා විධානයන් මත සිදුවී ඇත්නම් ඔබ කළ යුත්තේ ශුන්‍ය පරීක්‍ෂණයක් කර එය හැසිරවීම පමණි:

    if (i == null) {
        // Handle this
    }
  3. අමාරුම එක .. GC විසින් දැනටමත් වස්තුව එකතු කර ඇත්නම් ... මෙය සාමාන්‍යයෙන් සිදුවන්නේ ඔබ නූල් භාවිතා කරමින් වස්තුවක් සොයා ගැනීමට උත්සාහ කරන්නේ නම් ... එනම්, එය වස්තුවේ නමින් සොයා ගැනීම නම්, GC දැනටමත් සිදුවිය හැකිය එය පිරිසිදු කර ඇත ... මෙය සොයා ගැනීම අසීරු වන අතර එය තරමක් ගැටලුවක් බවට පත්වනු ඇත ... මෙය විසඳීමට වඩා හොඳ ක්‍රමයක් වන්නේ සංවර්ධන ක්‍රියාවලියේදී අවශ්‍ය ඕනෑම තැනක ශුන්‍ය පරීක්‍ෂා කිරීමයි. මෙය ඔබට බොහෝ කාලයක් ඉතිරි කර දෙනු ඇත.

නමෙන් සොයාගැනීමෙන් මා අදහස් කරන්නේ යම් රාමුවක් මඟින් නූල් භාවිතා කරමින් FIndObjects වෙත ඉඩ ලබා දෙන අතර කේතය මේ ආකාරයට විය හැකිය: FindObject ("ObjectName");


3
ඔබට යම් වස්තුවක් ගැන සඳහනක් තිබේ නම්, GC කිසි විටෙකත් එය පිරිසිදු නොකරයි
ජෝන් සෝන්ඩර්ස්

2
ඔබ FindObject ("වස්තුවේ නම") වැනි දෑ භාවිතා කරන්නේ නම්, ඔබ එම වස්තුව නැවත යොමු කිරීමට යන බව GC විසින් දැන ගැනීමට පෙර ක්‍රමයක් නොමැත .. මෙය පැහැදිලි කිරීමට උත්සාහ කළේ මෙයයි .. මේවා ක්‍රියාත්මක වන්නේ ක්‍රියාත්මක වේ
ආකාෂ් ගුතා

2
යුනිටි වැනි C # හි මෙම ක්‍රියාකාරිත්වය සපයන සමහර රාමු තිබේ. ප්‍රශ්නයට BCl හා සම්බන්ධ කිසිවක් නැත. විවේචනය කිරීමට පෙර අන්තර්ජාලය තුළ සොයන්න ඒවා වැනි කාර්යයන් රාශියක් ඇති අතර ඔබේ කාරුණික තොරතුරු සඳහා මම එය දිනපතා භාවිතා කරමි. දැන් කරුණාකර මට කියන්න, පිළිතුර කිසිදු විකාරයක් නොකරන්නේ කෙසේද.
ආකාෂ් ගුතා

2
docs.unity3d.com/ScriptReference/… සබැඳිය පරීක්ෂා කර අපව නිවැරදි කරන්න mr.expert: p
ආකාෂ් ගුතා

ඔබගේ සබැඳියේ මා දුටු උදාහරණ මගින් GameObject.Find හි ප්‍රති results ල සාමාජික ක්ෂේත්‍රයකට ලබා දේ. එය යොමු කිරීමක් වන අතර අඩංගු වස්තුව එකතු වන තුරු GC එය එකතු නොකරයි.
ජෝන් සෝන්ඩර්ස්

1

NullReferenceExeption නිවැරදි කිරීමට පහසුම ක්‍රමය ක්‍රම දෙකක් ඇත. ඔබට ස්ක්‍රිප්ට් එකක් අමුණා ඇති ගේම් ඕබෙක්ට් එකක් තිබේ නම් සහ ආර්බී (රිගිඩ්බෝඩි) නම් විචල්‍යයක් තිබේ නම්, ඔබ ඔබේ ක්‍රීඩාව ආරම්භ කරන විට මෙම විචල්‍යය ශුන්‍ය වනු ඇත.
පරිගණකයේ එම විචල්‍යයේ දත්ත ගබඩා කර නොමැති නිසා ඔබට NullReferenceExeption එකක් ලැබෙන්නේ මේ නිසා ය.

මම උදාහරණයක් ලෙස RigidBody විචල්‍යයක් භාවිතා කරමි.
අපට ක්‍රම කිහිපයකින් දත්ත සැබවින්ම පහසුවෙන් එකතු කළ හැකිය:

  1. AddComponent> Physics> Rigidbody සමඟ ඔබේ වස්තුවට RigidBody එක් කරන්න
    ඉන්පසු ඔබේ ස්ක්‍රිප්ටයට ගොස් ටයිප් කරන්න rb = GetComponent<Rigidbody>();
    මෙම කේත රේඛාව ඔබේ Start()හෝ Awake()කාර්යයන් යටතේ වඩාත් හොඳින් ක්‍රියාත්මක වේ.
  2. ඔබට ක්‍රමලේඛයෙන් සංරචකයක් එක් කළ හැකි අතර එක් කේත පේළියක් සමඟ විචල්‍යය එකවර පැවරිය හැකිය: rb = AddComponent<RigidBody>();

වැඩිදුර සටහන්: ඔබේ වස්තුවට [RequireComponent(typeof(RigidBody))]සං component ටකයක් එක් කිරීමට ඔබට අවශ්‍ය නම් සහ එකක් එකතු කිරීමට ඔබට අමතක වී ඇත්නම්, ඔබට ඔබේ පන්ති ප්‍රකාශයට ඉහළින් ටයිප් කළ හැකිය (ඔබගේ සියලු භාවිතයන්ට වඩා අඩු ඉඩ).
විනෝද වෙමින් විනෝද ක්‍රීඩා කරන්න!


-1

මෙම ව්‍යතිරේකය විසි කළ හැකි පොදු අවස්ථා අපි සලකා බලන්නේ නම්, ඉහළින් ඇති වස්තුව සමඟ ගුණාංග වෙත ප්‍රවේශ වීම.

උදා:

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

මෙහි දී, ලිපිනය ශුන්‍ය නම්, එවිට ඔබට NullReferenceException ලැබෙනු ඇත.

එබැවින්, එවැනි වස්තූන්ගේ ගුණාංග වෙත ප්‍රවේශ වීමට පෙර (විශේෂයෙන් ජනක වශයෙන්) අපි සෑම විටම ශුන්‍ය චෙක්පතක් භාවිතා කළ යුතුය.

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

-3

මෙය මූලික වශයෙන් ශුන්‍ය යොමු ව්‍යතිරේකයකි . ලෙස මයික්රොසොෆ්ට් states-

ඔබ අගය අවලංගු වන වර්ගයක සාමාජිකයෙකුට ප්‍රවේශ වීමට උත්සාහ කරන විට NullReferenceException ව්‍යතිරේකය විසි කරනු ලැබේ.

ඒ කියන්නේ මොකද්ද?

එයින් අදහස් වන්නේ කිසියම් වටිනාකමක් නැති සහ යම් කාර්යයක් කිරීමට අප එම සාමාජිකයා පත් කරන්නේ නම් පද්ධතිය නිසැකවම පණිවිඩයක් විසි කර කියනු ඇත-

"හේයි ඉන්න, එම සාමාජිකයාට කිසිදු වටිනාකමක් නැති නිසා ඔබ එය භාර දෙන කාර්යය ඉටු කළ නොහැක."

ව්යතිරේකය විසින්ම යමක් යොමු කරනු ලබන නමුත් ඒවායේ වටිනාකම නියම කර නොමැති බව පවසයි. එබැවින් මෙය ඇඟවෙන්නේ අගය වර්ග භාවිතා කළ නොහැකි බැවින් යොමු වර්ග භාවිතා කරන විට පමණි.

අපි අගය වර්ගයේ සාමාජිකයන් භාවිතා කරන්නේ නම් NullReferenceException සිදු නොවේ.

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

ඉහත කේතය මඟින් ශුන්‍ය අගයක් සහිත සරල නූලක් පෙන්වයි .

දැන්, මම වැල දිග මුද්රණය කිරීමට උත්සාහ කරන විට, STR , මම ලබා ගන්නේ කෙසේද වර්ගය 'System.NullReferenceException' ක unhandled ව්යතිරේකයක් පණිවිඩය සාමාජික නිසා STR ශූන්ය කිරීමට යොමු වන අතර ශූන්ය ඕනෑම දිග ඇති විය නොහැකි ය.

විමර්ශන වර්ගයක් ක්ෂණිකව දැක්වීමට අපට අමතක වූ විට ' NullReferenceException ' ද සිදු වේ.

මට එහි පන්ති සහ සාමාජික ක්‍රමයක් ඇතැයි සිතමු. මම මගේ පන්තිය ක්ෂණිකව සකසා නැති නමුත් මගේ පන්තිය නම් කළෙමි. දැන් මම ක්‍රමය භාවිතා කිරීමට උත්සාහ කළහොත්, සම්පාදකයා දෝෂයක් විසි කරයි හෝ අනතුරු ඇඟවීමක් කරයි (සම්පාදකයා මත පදනම්ව).

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

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

    }
}

ඉහත කේතය සඳහා සම්පාදකයා විසින් විචල්ය obj නියම කර නොමැති බවට දෝෂයක් මතු කරයි, එයින් ඇඟවෙන්නේ අපගේ විචල්‍යයට ශුන්‍ය අගයන් හෝ කිසිවක් නොමැති බවයි. ඉහත කේතය සඳහා සම්පාදකයා විසින් විචල්ය obj නියම කර නොමැති බවට දෝෂයක් මතු කරයි, එයින් ඇඟවෙන්නේ අපගේ විචල්‍යයට ශුන්‍ය අගයන් හෝ කිසිවක් නොමැති බවයි.

එය සිදු වන්නේ ඇයි?

  • NullReferenceException පැන නගින්නේ වස්තුවේ වටිනාකම පරික්ෂා නොකිරීමේ අපගේ දෝෂය හේතුවෙනි. කේත සංවර්ධනයේදී අපි බොහෝ විට වස්තු අගයන් පරික්‍ෂා නොකරමු.

  • අපගේ වස්තූන් ක්ෂණිකව දැක්වීමට අමතක වූ විට ද එය පැන නගී. ආපසු හැරවීමට හෝ ශුන්‍ය අගයන් සැකසීමට හැකි ක්‍රම, ගුණාංග, එකතු කිරීම් ආදිය භාවිතා කිරීම ද මෙම ව්‍යතිරේකයට හේතුව විය හැකිය.

එය වළක්වා ගන්නේ කෙසේද?

මෙම කීර්තිමත් ව්‍යතිරේකය වළක්වා ගැනීම සඳහා විවිධ ක්‍රම සහ ක්‍රම තිබේ:

  1. පැහැදිලිව පරීක්ෂා කිරීම: වස්තූන්, ගුණාංග, ක්‍රම, අරා සහ එකතු කිරීම් අහෝසි දැයි පරීක්ෂා කිරීමේ සම්ප්‍රදායට අප අනුගත විය යුතුය. If-else if-else වැනි කොන්දේසි සහිත ප්‍රකාශ භාවිතා කරමින් මෙය සරලව ක්‍රියාත්මක කළ හැකිය.

  2. ව්‍යතිරේකය හැසිරවීම: මෙම ව්‍යතිරේකය කළමනාකරණය කිරීමේ වැදගත් ක්‍රමයක්. සරල උත්සාහක-අවසාන-වාරණ භාවිතා කිරීමෙන් අපට මෙම ව්‍යතිරේකය පාලනය කළ හැකි අතර එහි ලොගයක් පවත්වා ගත හැකිය. ඔබේ යෙදුම නිෂ්පාදන අවධියේ සිටින විට මෙය ඉතා ප්‍රයෝජනවත් වේ.

  3. ශුන්‍ය ක්‍රියාකරුවන්: වස්තු, විචල්‍යයන්, ගුණාංග සහ ක්ෂේත්‍ර සඳහා අගයන් සැකසීමේදී ශුන්‍ය සමතුලිත ක්‍රියාකරු සහ ශුන්‍ය කොන්දේසි සහිත ක්‍රියාකරුවන් ද ප්‍රයෝජනවත් ලෙස භාවිතා කළ හැකිය.

  4. නිදොස්කරණය: සංවර්ධකයින් සඳහා, අප සමඟ නිදොස් කිරීමේ විශාල ආයුධය අප සතුව ඇත. සංවර්ධන මුහුණුවර තුළ අප NullReferenceException වලට මුහුණ දී ඇත්නම්, අපට නිදොස්කරණය භාවිතා කර ව්‍යතිරේකයේ ප්‍රභවය ලබා ගත හැකිය.

  5. සාදන ලද ක්‍රමය: GetValueOrDefault (), IsNullOrWhiteSpace () සහ IsNullorEmpty () වැනි පද්ධති ක්‍රම මඟින් ශුන්‍යයන් පරික්ෂා කර ශුන්‍ය අගයක් තිබේ නම් පෙරනිමි අගය ලබා දේ.

දැනටමත් මෙහි හොඳ පිළිතුරු බොහොමයක් තිබේ. ඔබට මගේ බ්ලොග් අඩවියේ උදාහරණ සමඟ වඩාත් සවිස්තරාත්මක විස්තරයක් පරීක්ෂා කළ හැකිය .

මෙයද උපකාරී වේ යැයි සිතමු!


ඔබ මූලික වශයෙන් එම බ්ලොග් සටහනෙන් අඩක් පිටපත් කර ඇති අතර පවතින පිළිතුරු ආමන්ත්‍රණය නොකරන අලුත් කිසිවක් එකතු කර නැත.
කෝඩ්කාස්ටර්

odcodecaster ඔබ ඔබේම බ්ලොග් අඩවියෙන් සාරාංශයක් නැවත ලියන විට එය පිටපත් කිරීමක් යැයි කියනු ලැබේ. මගේ පිළිතුරේ අළුත් දෙයක් නැති බවත් පෙර පිළිතුරු වලට අළුත් දෙයක් නැති බවත් මම දනිමි. එහෙත් වඩාත් නවීන ආකාරයකින් දායක වීමටත් මා තේරුම් ගත් ආකාරය අන් අයට තේරුම් ගැනීමටත් මම කැමැත්තෙමි. එය තනි පුද්ගලයෙකුට උපකාර කළත් සතුටු වනු ඇත. හොඳ විශ්වාසයකින්.
වසීම්

-4

ගොඩනැගීම සුරැකීමේදී හෝ සම්පාදනය කිරීමේදී යමෙකුට මෙම පණිවිඩය ලැබෙන්නේ නම්, සියලු ලිපිගොනු වසා දමා සම්පාදනය කර සුරැකීමට ඕනෑම ගොනුවක් විවෘත කරන්න.

මට හේතුව වූයේ මම ගොනුව නැවත නම් කර තිබීම සහ පැරණි ගොනුව තවමත් විවෘතව තිබීමයි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.