„C“ („var“) išvestis iš „??“ nulinis koordinatorius

Aš perskaičiau daugybę SO klausimų apie nulinį derinimą ?? bet nė vienas iš jų, atrodo, neturi įtakos šiai konkrečiai problemai, kuri nėra susijusi su negaliojimu ( čia ), operatoriaus prioritetu ( čia ir čia ) arba ypač netiesiogine konversija ( čia , čia , čia ir čia ). Taip pat perskaitysiu .NET dokumentus (daugiau informacijos čia ) ir bandžiau perskaityti oficialią specifikaciją , tačiau, deja, visi be jokios naudos.


Taigi čia. Vienintelis skirtumas tarp šių dviejų eilučių yra naudoti var kad būtų galima daryti išvadą dėl antrojo tipo, palyginti su aiškiu pirmojo tipo Random , tačiau antroji eilutė pateikia klaidą, kaip parodyta, o pirmasis - tik gerai.

 Random x = new Random() ?? (x = new Random()); // ok var y = new Random() ?? (y = new Random()); // CS0841 // ^-------- error here 

CS0841: Nepavyko naudoti vietinio kintamojo „y“ prieš jį paskelbiant

Kas yra antroji eilutė, dėl kurios rezultatas yra neaiškus?

Iš aukščiau paminėto „hubub“ aš sužinojau, kad galimybė yra kairėje pusėje ?? operatorius, kuris yra null įveda priklausomybę nuo faktinio jo dešinės pusės vykdymo laiko apibrėžimo. Na, gerai, manau, kad tai, ką reiškia? Galbūt pavojaus signalas apskritai pasiekiamas ?? operatorius šioje svetainėje turėjo būti tam tikras baisus įspėjimas ...

Dabar, kai aš pradėjau nuo nulio, aš maniau, kad visas var raktinio žodžio taškas (kaip ypač priešingas dynamic ) yra tai, kad pagal apibrėžimą toks suvokimas nebuvo suvokiamas.

Kitaip tariant, net jei priimame konservatyvią, bet gana pagrįstą taisyklę „niekada nežiūrėdami už bet kokios užduoties ribų - operatoriaus“, tokiu būdu mes negavome naudingos informacijos, iš kurios dešinės pusės ?? tada, remiantis tik kairėje pusėje, bendras rezultatas turi būti „suderinamas su“ Random . Tai reiškia, kad rezultatas turėtų būti Random arba konkretesnis (išvestas) tipas; jis negalėjo būti bendresnis. Taigi, pagal apibrėžimą, neturėtų būti daroma prielaida, kad šiuo atveju Random tipas būtų naudojamas?

Kiek aš galiu pasakyti, sugadinti var dėl vykdymo laiko sumažina jo paskirtį. Ar ne toks dynamic ? Todėl manau, kad šie klausimai yra:

  • Ar nulinis koalescuojantis operatorius yra viena ir (arba) reta išimtis iš mano supratimo apie C # statinio įvedimo filosofiją (t. Y. Kompiliavimo laiką)?
  • Jei taip, kokie yra šio dizaino privalumai ir kompromisai, o tai, kas, atrodo, čia vyksta, ty sąmoningai įvedant ne determinizmą į statinio tipo išvesties sistemą, kurios ji anksčiau nebuvo parodyta? Nepavyko įgyvendinti dynamic , nesukreipiant statinio spausdinimo grynumo?
  • Ar ne vienas iš pagrindinių stiprios įvedimo punktų, kad būtų užtikrintas dizaino griežtumas rengiant laiką su faktiniu kūrėjo atsiliepimu? Kodėl negalime palaikyti griežto konservatyvumo politikos - visada rašydami konkretų tipą, kuris gali būti statiškai išvestas, o nulinės koalencinės veiklos vykdytojas, remdamasis ateities informacija, daro viską, ką nori?
4
09 июля '17 в 4:59 2017-07-09 04:59 „Glenn Slayden“ yra nustatytas liepos 09 d. 17 val. 4:59 2017-07-09 04:59
@ 2 atsakymai

Tai nėra laiko svarstymas.

Kintamojo, kuris deklaruojamas naudojant var , sudarymo laiko tipas yra statinis jo iniciatoriaus tipas. Statinis tipas ?? išraiška yra bendras abiejų operandų tipo statinis tipas. Tačiau statinis antrojo operando tipas yra statinis y tipas, kuris nėra žinomas. Todėl nežinomas visas iniciatoriaus tipas, o produkcija neatliekama.

Tiesa, yra tipų, kurių inicijavimas būtų nuoseklus, tačiau jų negalima rasti naudojant C # išvados taisykles.

4
09 июля '17 в 5:43 2017-07-09 05:43 Atsakymą pateikė Ben Voigt, liepos 09, 17, 5:43 2017-07-09 05:43

Kai naudojate var , tipas apskaičiuojamas kompiliavimo metu. Todėl rašydami:

 var y = new Random() ?? (y = new Random()); 

kompiliatorius negali nustatyti, kokio tipo y yra kompiliavimo metu ir todėl pradeda rėkti - nuspręsti, ar kairė pusė yra ?? null arba ne, bus nustatyta vykdymo metu.

Geriausias pavyzdys:

 public interface IA { void Do(); } public class A : IA { ... } public class B : IA { ... } A a = null; var something = a ?? new B(); 

Koks turėtų būti something : IA , A ar B ?

0
09 июля '17 в 5:19 2017-07-09 05:19 atsakymą pateikė CodingYoshi liepos 09 '17, 17:19 2017-07-09 05:19