De ce am primit eroarea de compilare „Use of unassigned local variable”? (Programare, C#,.Net)

theknut a intrebat.

Codul meu este următorul

int tmpCnt;  
if (name == "Dude")  
   tmpCnt++;  

De ce apare o eroare „Use of unassigned local variable tmpCnt” (Utilizarea unei variabile locale neatribuite)?

Știu că nu am inițializat-o în mod explicit, dar din cauza Tabelul valorilor implicite un tip de valoare este inițializat cu 0 oricum. Referința îmi amintește și de referință:

Nu uitați că utilizarea variabilelor neinițializate în C# nu este permisă.

Dar de ce trebuie să o fac în mod explicit dacă este deja făcut în mod implicit? Nu ar fi un câștig de performanță dacă nu ar trebui să o fac?

Comentarii

  • Mă poate ajuta cineva cu titlul? Nu am putut găsi o potrivire pentru acesta :-S – -.  > Por theknut.
  • Am un struct local, niciodată inițializat, compilează fără erori. Azi am creat un alt struct, tratat identic, am primit „uninitialized local variable error”. Toate structurile sale membri au fost setați la o valoare înainte de utilizare, dar nu am putut să o setez mai întâi la null, deoarece era „doar” un struct. Structura care a fost compilată conținea doar ints, bools și șiruri de caractere. Cea care a dat eroare conținea și DateTimes. „MyStructType myStruct = new MyStructType();” a eliminat eroarea. Nu este prima dată când am fost mușcat de faptul că am ratat ceva la câteva niveluri mai jos. –  > Por MickeyfAgain_BeforeExitOfSO.
  • Possible duplicate of De ce trebuie inițializate variabilele locale C#? –  > Por Olivier Rogier.
10 răspunsuri
James Michael Hare

Variabilele locale nu sunt inițializate. Trebuie să le inițializați manual.

Membrii sunt inițializate, de exemplu:

public class X
{
    private int _tmpCnt; // This WILL initialize to zero
    ...
}

Dar variabilele locale nu sunt:

public static void SomeMethod()
{
    int tmpCnt;  // This is not initialized and must be assigned before used.

    ...
}

Deci codul dvs. trebuie să fie:

int tmpCnt = 0;  
if (name == "Dude")  
   tmpCnt++;  

În concluzie, membrii sunt inițializați, iar variabilele locale nu. Acesta este motivul pentru care apare eroarea de compilare.

Comentarii

  • Vă mulțumim! Nu știam despre diferența dintre membrii și variabilele locale +1 –  > Por theknut.
  • @James: știți dacă aceasta este doar o caracteristică a compilatorului pentru a preveni o astfel de greșeală sau dacă compilatorul C# întârzie efectiv alocarea memoriei pentru membrii locali declarați până la atribuire? (De exemplu, în C++, utilizarea unei variabile neatribuite este „ok”, chiar dacă valoarea unei astfel de variabile este imprevizibilă). –  > Por ybakos.
  • Caracteristica compilatorului pentru a evita greșeala. Memoria (care, desigur, este doar o referință pentru tipurile de referință) pentru local este alocată la declarare. –  > Por James Michael Hare.
  • Pentru a evita ce greșeală? –  > Por Raikol Amaro.
  • folosind newish out var variable sintaxa dă și acest avertisment, cred că acest caz este enervant –  > Por mkb.
Serghei Kalinichenko

Atribuțiile implicite se aplică membrilor clasei, dar nu și variabilelor locale. După cum a explicat Eric Lippert în acest răspuns, Microsoft ar fi putut avea inițializat în mod implicit variabilele locale, dar a ales să nu o facă deoarece utilizarea unei variabile locale neatribuite este aproape sigur un bug.

Comentarii

  • Acest lucru răspunde, de fapt, la întrebarea OP. –  > Por Raikol Amaro.
  • @Raikol Amaro: *OP’s –  > Por Peter Mortensen.
  • Da. OP’s. Mulțumesc pentru corecție. –  > Por Raikol Amaro.
Joe

Următoarele categorii de variabile sunt clasificate ca fiind inițial neatribuite:

  • Variabile de instanță ale variabilelor struct neatribuite inițial.
  • Parametrii de ieșire, inclusiv variabila this a constructorilor de instanțe struct.
  • Variabile locale, cu excepția celor declarate într-o clauză catch sau într-o instrucțiune foreach.

Următoarele categorii de variabile sunt clasificate ca fiind inițial alocate:

  • Variabile statice.
  • Variabile de instanță ale instanțelor de clasă.
  • Variabile de instanță ale variabilelor structurale atribuite inițial.
  • Elemente de tablouri.
  • Parametrii de valoare.
  • Parametrii de referință.
  • Variabilele declarate într-o clauză catch sau într-o instrucțiune foreach.

Damith

Variabilele locale nu au o valoare implicită.

Ele trebuie să fie atribuite definitiv înainte de a le utiliza. Acest lucru reduce șansa de a utiliza o variabilă căreia crezi că i-ai dat o valoare sensibilă, când de fapt are o valoare implicită.

Comentarii

  • Nu ar fi acesta un argument pentru ca nici variabilele de instanță și variabilele de clasă să nu aibă valori implicite (ele au valori implicite)? –  > Por Peter Mortensen.
nabrond

Tabelul cu valori implicite se aplică numai la inițializarea unei variabile.

Conform paginii legate, următoarele două metode de inițializare sunt echivalente…

int x = 0;
int x = new int();

În codul dvs., ați definit pur și simplu variabila, dar nu ați inițializat niciodată obiectul.

zar

O greșeală foarte stupidă, dar se poate întâmpla asta și cu o clasă dacă nu ai instanțiat-o.

BankAccount account;
account.addMoney(5);

Cele de mai sus vor produce aceeași eroare întrucât:

class BankAccount
{
    int balance = 0;
    public void addMoney(int amount)
    {
        balance += amount;
    }
}

Faceți următoarele pentru a elimina eroarea:

BankAccount account = new BankAccount();
account.addMoney(5);

Cody Gray

Variabilele locale nu sunt inițializate automat. Acest lucru se întâmplă numai cu variabilele la nivel de instanță.

Trebuie să inițializați în mod explicit variabilele locale dacă doriți ca acestea să fie inițializate. În acest caz, (așa cum explică documentația legată) fie prin setarea valorii 0, fie prin utilizarea funcției new operator.

Codul pe care l-ați prezentat încearcă într-adevăr să utilizeze valoarea variabilei tmpCnt înainte ca aceasta să fie inițializată cu ceva, iar compilatorul avertizează pe bună dreptate în legătură cu acest lucru.

Msonic

Consultați acest fir de discuție privind bools neinițializate, dar ar trebui să vă răspundă la întrebare.

Variabilele locale nu sunt inițializate decât dacă apelați constructorii lor (new) sau dacă le atribuiți o valoare.

Ronika
IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize

Atribuiți valoarea(_getCurrentHolidayList) în interiorul buclei

foreach (HolidaySummaryList _holidayItem in _holidayDetailsList)
{
                            if (_holidayItem.CountryId == Countryid)
                                _getCurrentHolidayList = _holidayItem.Holiday;                                                   
}

După ce treceți varibala locală către o altă metodă ca mai jos. Se aruncă o eroare (utilizarea unei variabile neatribuite). chiar dacă nullable a fost menționat în momentul decalării.

var cancelRescheduleCondition = GetHolidayDays(_item.ServiceDateFrom, _getCurrentHolidayList);

dacă ați menționat ca mai jos, nu va fi emisă nicio eroare.

IEnumerable<DateTime?> _getCurrentHolidayList =null;

Sofian Hnaide

În timp ce tipurile de valori au valori implicite și nu pot fi nule, acestea trebuie, de asemenea, să fie inițializate în mod explicit pentru a putea fi utilizate. Vă puteți gândi la aceste două reguli ca fiind reguli alăturate.

Tipurile de valori pot nu pot fi fi nule → compilatorul garantează acest lucru. dacă vă întrebați cum, mesajul de eroare pe care l-ați primit este răspunsul. Odată ce ați apelat constructorii lor, acestea au fost inițializate cu valorile lor implicite.

int tmpCnt; // Not accepted
int tmpCnt = new Int(); // Default value applied tmpCnt = 0

Comentarii

  • Nu depinde mai mult de tipul de variabilă decât de faptul că este un tip de valoare sau un tip de referință? Nu sunt variabile de instanță de tip valoare nu sunt inițializate automat la valoarea implicită? –  > Por Peter Mortensen.

Tags:,