Hech qanday () * null mos yozuvlar istisnosiz qoldirish uchun emas, balki kutish aqlga sig'dirolmaydimi?

When you create an extension method you can, of course, call it on null.But, unlike an instance method call, calling it on null doesn't have to throw a NullReferenceException -> you have to check and throw it manually.

Any() Linq kengaytmasi usuli qo'llanilishi uchun Microsoft ularni ArgumentNullException ( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src /System/Linq/AnyAll.cs ).

It irks me to have to write if( myCollection != null && myCollection.Any() )

Men ushbu kodning mijozi sifatida noto'g'ri ekansiz, masalan, ((int []) bo'sh) .Any() kodni FALSE qaytarish kerakmi?

40
Ikkita fikr: 1. Sizning umumiy dizayningiz qayta ishlangan bo'lishi mumkin, shuning uchun oldindan qo'shimcha null tekshirishingiz kerak emas? Boshqacha qilib aytganda, IEnumerable kodini qaytaradigan usullar hech qachon null kodini qaytarmasligi kerak, aks holda bu bo'sh holga ega. 2. kengaytma usulini yarating va uni o'rniga foydalaning: public static bool IsNullOrEmpty (bu IEnumerable manba) {qaytib keladigan manba? Any ()! = True; }
qo'shib qo'ydi muallif Will Dean, manba
har bir LINQ usuli null argumentga ishora etishi kerak. har qanday faqat izchil.
qo'shib qo'ydi muallif Allen Bargi, manba
Kodning kodi null to'plamni qaytib kelishi bilan qiziqib qolaman. Menimcha, bu muammo Any() xatti-harakatlarida emas, balki sizning usulingiz yoki mulkingizdan nol bo'lganingizning xatti-harakatlarida. To'plamni qaytaruvchi a'zodan nullga qaytish uchun hech qanday asos yo'q.
qo'shib qo'ydi muallif hao, manba
Ushbu sayt uchun bu juda mensimaydi, biroq men null to'plamni va bo'sh to'plamni aynan bir xil muomalaga kiritganimda nullani tekshirish haqida doimo bezovtaman. Shu bilan birga, bu nol ko'rsatkichni bo'sh to'plamga nisbatan mazmunli bo'lsa ("Natijalarsiz qidiruv natijalari" ga qarshi null bo'lsa, qidiruv natijalarini yashirish uchun) bo'shab qoladi.
qo'shib qo'ydi muallif DenNukem, manba
Eslatma: CA2201 ish vaqti uchun ajratilgan NullReferenceException deb hisoblaydi. Bu faqat null aslida ajratilgan bo'lsa tashlanishi kerak. Uni o'zingizning kodingizdan aniq tashlab qo'ymang.
qo'shib qo'ydi muallif Marcos, manba
qo'shib qo'ydi muallif user8669, manba
@SebastianRedl: LINQ'dan oldin ham null to'plamlarida C# foreach tuguniga boqildi, shuning uchun ularni "izchil" deb hisoblashingiz mumkin.
qo'shib qo'ydi muallif dan04, manba
Kengaytma usuli yaratish IList EmptyIfNull (bu IList ) {agar (u == null) yangi ro'yxatni qaytaradi (); thing.EmptyIfNull() funktsiyasidan foydalanishingiz mumkin. ()
qo'shib qo'ydi muallif Alireza Abdollahi, manba
@ JesseC.Slicer Bu sizning kodingiz qanday tashkil etilganiga bog'liq. Agar siz IEnumerable funksiyasini qaytaradigan funksiyani taklif qilsangiz va uni darhol o'sha ko'lamda ishlasa, siz uning shartnomasiga muvofiq ishlaydigan usuliga tayanilasiz. Ammo, agar u boshqa funktsiyaga argumentli bo'lsa, u funktsiya null dan hech qachon o'tib ketuvchiga tayanmasligi kerak. Men faqat null holatini hisobga olishdan qochish uchun qo'shimcha funktsiyalar yaratishdan qochmaslik kerak. Shunday qilib, bu muammon muqarrar ravishda ba'zi joylarda paydo bo'ladi.
qo'shib qo'ydi muallif jmibanez, manba
To'liq bajaring: kodni Error.ArgumentNull funktsiyasi kabi yozmang. Bu, albatta, dahshatli narsalar. Yon suzuvchi vintlardek o'qilishi qiyin. Faqatgina istisnoga yo'l qo'ying.
qo'shib qo'ydi muallif jmibanez, manba
Hatto nol ko'rsatkichni yaratuvchisi ham uning milliard dollar xatosi deb nom beradi. Hozirgacha tajribamda, null ma'lumotlardan ko'ra, har doim ham yaxshi echim bor. Shu nuqtai nazardan, tilni noldan foydalanishni yanada qulayroq qilish u bilan yoziladigan kod sifatini pasaytiradi.
qo'shib qo'ydi muallif R. Schmitz, manba
@ 17of26: == true kerakmi?
qo'shib qo'ydi muallif Kent, manba
@ 17of26: javobingiz uchun tashakkur. Men null C #da yolg'onchi deb o'yladim.
qo'shib qo'ydi muallif Kent, manba
C # 6 da, agar siz (myCollection? .Any() == true)
qo'shib qo'ydi muallif Minihawk, manba
@EricDuminil Ha, chunki "myCollection?" Iborasi uchta mumkin bo'lgan holatlar mavjud: haqiqiy, noto'g'ri, null
qo'shib qo'ydi muallif Minihawk, manba
Xo'sh, nima uchun bu birinchi navbatda bo'sh? Siz nolni bo'sh deb hisoblashni xohlamaysiz, chunki bo'sh emas, bu butunlay boshqa narsa. Ehtimol, bu sizning ishingizdagi bo'shlik deb hisoblashni xohlaysiz, lekin tilga bunday narsalarni qo'shish xatolarga olib keladi.
qo'shib qo'ydi muallif immibis, manba
Shuning uchun koleksiyalar bilan ishlashda null kodini qaytarmasligingiz kerak, lekin buning o'rniga bo'sh holatlardan foydalaning.
qo'shib qo'ydi muallif Tobias Sette, manba
Shuni esda tutingki, kengaytma usuli aslida mavjud turga "qo'shilgan" statik usul bo'lib, chaqiruvchi misolni parametr sifatida qabul qiladi. Ya'ni, myCollection.Any() ni bajarganingizda, aslida nima qilayotganingizni MyCollectionType.Any (myCollection) ; shuning uchun ArgumentNullException mantiq.
qo'shib qo'ydi muallif Nate, manba
Nullabalovchi mos yozuvlar turlariga ega bo'lish bu muammoni engillashtirishi kerak: msdn. microsoft.com/en-us/magazine/…
qo'shib qo'ydi muallif Matthew, manba
@JoshPart nima degani.
qo'shib qo'ydi muallif Sqrs, manba
Boshqa nol tillar bilan birgalikda ishlashni istisno qilish uchun nulllarni ishlatmagan F # da ham null |> Seq.isEmpty System.ArgumentNullException: qiymat null bo'lmasligi mumkin . Kutilgan narsa, siz kutilgan narsalar uchun aniq bo'lmagan qadriyatlardan o'tmasligingiz kabi ko'rinadi, shuning uchun siz nol bo'lganingizda hali ham istisno. Agar bu boshlash masalasi bo'lsa, null o'rniga bo'sh ketma-ketlik bilan boshlayman.
qo'shib qo'ydi muallif Zach, manba
Barqarorlik sabablari bor, biroq EDD nuqtai nazaridan o'rganaylik. Agar "to'p" har qanday to'plamga "qo'ng'iroq" deb javob bersa, ular o'yinlarni qidiradi, nullada o'yinlarni qidirib topish nuqtasi nimada, agar kolleksiyangiz noto'g'ri bo'lsa? Muammolarni har qanday qo'shish kerakmi? Nima bo'lishidan qat'iy nazar, savollar github-da javob berilgan;)
qo'shib qo'ydi muallif user143241, manba
Menimcha, kodni foo ga kiritish uchun C# kodini kengaytirish metodlari qo'shilganda foo.Bar dan keyin null (); birdan keskin ravishda to'xtatilgan bo'lsa, bu juda mudhish o'zgarish edi. Odatda, "haqiqiy" uslublar kabi muomala qiladigan kengaytma usullarini yozishingiz kerak, shuning uchun this argumenti null bo'lsa, istisno qo'yasiz.
qo'shib qo'ydi muallif ohias, manba
@ jpmc26 throw Error.XXX kodi butunlay yaxshi va aqlli. Istisno tashlanmaguncha, suyak izi populyatsiya qilinmaydi, shuning uchun stak izlari haqida odatiy hech narsa yo'q. Boilerplate istisnosini yaratishni qayta tiklash okunabilirliği oshiradi va kelajakda o'zgarishlar beradi.
qo'shib qo'ydi muallif Johnbot, manba

13 javoblar

Menda beshta kartoshka bo'lgan sumka bor. Kartochkada .Any() kartoshka bormi?

"Yes," you say. <= true

Men kartoshkaning hammasini olib, ularni eb olaman. Kartochkada .Any() kartoshka bormi?

"No," you say. <= false

To'pni olovda yondirib yuboraman. Kartochkada .Xo'sh har qanday() kartoshka bormi?

"There is no bag." <= ArgumentNullException

148
qo'shib qo'ydi
Agar mening qo'lim ( Bag kartoshka; ) hech qanday ( potato = null; ) o'z ichiga olmaydi va men buni ko'rsatib: "Bu qopqoqda kartoshka bormi?" ( agar bo'lsa (potatos.Any ()) {} ). Menga g'alati tarzda qarash va "Qanday yukxalta, u erda hech qanday sumkangiz yo'q!" Deb ayta olasiz. (Istisno qilish).
qo'shib qo'ydi muallif user109758, manba
@IsmaelMiguel chindan ham emas, qizib ketgan kartoshka bilan to'ldirgan va hech qanday sumkasi bilan o'ralgan kartoshka bilan to'ldirishi mumkin edi :)
qo'shib qo'ydi muallif jwenting, manba
@IsmaelMiguel nima uchun sumkaga olovni solib, kartoshkani pishirish uchun ishlatmaslik kerakmi?
qo'shib qo'ydi muallif jwenting, manba
@ D.BenKnoble: Mashinamdagi magistralni ko'rmay turib, mashinamning tanasida hech qanday jasad yo'qligiga shahodat berishni xohlaysizmi? Yo'q, yo'qmi? Magistralni tekshirish va hech narsa topmaslik yoki magistralni tekshirmaslik o'rtasidagi farq nima? Siz har ikkala holatda ham bir xil miqdordagi jismlarni ko'rganingiz uchun hozirgina guvohlik bera olmaysizmi? ... Bu farq. Siz aslida uni birinchi marta tasdiqlash imkoniga ega bo'lmasangiz, biror narsaga kafolat bera olmaysiz. Siz ikkalasini teng deb hisoblaysiz, lekin bu berilgan emas. Ba'zi hollarda bu ikkisi orasida muhim farq bo'lishi mumkin.
qo'shib qo'ydi muallif Flater, manba
Agar halok bo'lgan muayyan paketga qaraganda yaxshiroq o'xshashlik bo'lsa, sizdan so'rayman-ki, sumkada hech qanday kartoshka yo'qmi, men aytayotgan sumkani aytmadim. Men so'radim sumka uchun sumka o'zgaruvchisi mos yozuvlar . Agar o'zgaruvchi aslida null bo'lsa, unda men aslida kartoshkani o'z ichiga olmaydi (nol kartoshkani o'z ichiga oladigan darajada asoslantirilgan bo'lishi mumkin) bo'lishi mumkin bo'lgan, Men hech qanday sumkaga murojaat qilolmayapman. Qanday true yoki false ham izchil javob emas; savol nuqsonli.
qo'shib qo'ydi muallif Ben, manba
@jwenting Ushbu ta'riflangan voqealar tartibini buzadi
qo'shib qo'ydi muallif Stumps, manba
@Oly Dan ovqatni ishlatishdan oldin va olovni yoqish uchun ularni olovda yondirib yubordi.
qo'shib qo'ydi muallif Stumps, manba
@ Xo'sh, u erda hech qanday joyda, ular bilan boshlash uchun xom kartoshka emas. Ehtimol, sumkada kartoshkani pishirishni g'alati deb bilaman, ammo biz kim bo'lamiz? : R.
qo'shib qo'ydi muallif user1491229, manba
amalda, kimdir noma'lum manbadan yopiq qutichni sizga topshiradi. Qutidagi yukxalta har qanday kartoshkadan iboratmi? Men faqat 2 stsenariyaga qiziqaman - A) qutidagi kartoshkada bir quti bor, yoki B) qutida kartoshka va/yoki sumka yo'q. Semantik tarzda, ha, null va bo'sh o'rtasida farq bor, lekin menga e'tibor bermaydigan vaqtning 99%.
qo'shib qo'ydi muallif dave thieben, manba
Xo'sh, kartoshkada kartoshka yo'qmi? Yolg'on so'zlar yolg'ondir ... (Men bunga rozi emasman, faqat ikkinchi bir kuzatasiz).
qo'shib qo'ydi muallif Andy, manba
Siz beshta xom kartoshkani yebdingizmi? Darhol shifokorga murojaat qiling.
qo'shib qo'ydi muallif Sierramike, manba

Birinchidan, manba kodi NullReferenceException emas, balki ArgumentNullException ni urib chiqadi.

Ko'p hollarda sizning to'plamingiz nol yo'qligini bilasiz, chunki bu kod faqatgina to'plam allaqachon mavjudligini biladigan koddan chaqiriladi, shuning uchun u erda nolli chekni juda tez qo'yish kerak emas. Lekin agar mavjudligini bilmasangiz, unda Any() ga qo'ng'iroq qilishdan oldin tekshirish kerak.

Ushbu kodning mijozi sifatida men noto'g'ri deb hisoblayman, masalan. ((int []) null) .Any() kodi FALSE qaytarish kerakmi?

Ha. Any() javoblari "bu to'plamda biron bir element mavjudmi?" Agar bu kollektsiya mavjud bo'lmasa, u holda savol o'zi bema'ni; u hech qanday narsalarni o'z ichiga olmaydi yoki yo'q qila olmaydi, chunki u mavjud emas.

50
qo'shib qo'ydi
@ChrisWohlert "semantik, mavjud bo'lmagan to'siq - bu bo'sh narsa". Ehtimol, to'siq nazariyasida bu to'g'ri, lekin biz bu erdagi nazariya nazariyasi bilan ishlamayapmiz.
qo'shib qo'ydi muallif JanC, manba
null tipida @ChrisWohlert turi mavjud emas, aks holda uni mos kelmaydigan turdagi narsalarga belgilash mumkin emas. null to'siq yoki ro'yxat yoki bo'sh bo'lishi mumkin bo'lgan boshqa narsa emas; T nima ekanligi muhim emas.
qo'shib qo'ydi muallif Matthew Read, manba
@ChrisWohlert Agar Add bo'lmasa, hech narsa to'plamni yaratmaslik kerak, nima uchun har qanday (va keyin uning bo'shligini aytib berish kerak)? Menga juda mos kelmaydigan ko'rinadi.
qo'shib qo'ydi muallif Andy, manba
@ChrisWohlert "A bo'sh narsa, B - tarvuz o'z ichiga olgan to'siq, bo'shmi? Ha, B bo'shmi? Yo'q C bo'shmi? Uhhh ..."
qo'shib qo'ydi muallif immibis, manba
Men null deyishga urinmayapman, faqat bitta to'plam mavjud bo'lmagan joyda hech narsa yo'q.
qo'shib qo'ydi muallif Chris Wohlert, manba
Va bu savolga teng, biron-bir maqola qo'yilganmi?
qo'shib qo'ydi muallif Chris Wohlert, manba
Yo'q, faqatgina biron-bir narsalar bor-yo'qligi haqida savol tug'iladi.
qo'shib qo'ydi muallif Chris Wohlert, manba
@ruakh Faqat T majmui
qo'shib qo'ydi muallif Chris Wohlert, manba
Albatta, bu qanday ishlaydi, va OP bu ochiq-oydin biladi, lekin semantik holda, mavjud bo'lmagan to'plam bo'sh elementdir. Har qanday holatda ham, siz qanday ma'noda ishlamasin, degan mazmunli ma'noga ega emasligini ta'kidlashingiz kerak.
qo'shib qo'ydi muallif Chris Wohlert, manba
@ruah bo'sh odam ni tashkil etuvchi ma'lumotni bilmayman, lekin men bo'sh kometalarni o'z ichiga olgan setni tasavvur qilaman, ha. Bundan tashqari, {{}, {}, {}, {}} . Biroq, bu faqat T to'plam bo'lsa, hisobga olinadi.
qo'shib qo'ydi muallif Chris Wohlert, manba
Biz ishonchimiz komil emas, lekin kutilgan narsalar haqida gapiryapmiz va ba'zi bir nazariyaga yoki konvensiyaga murojaat qilishimizga to'g'ri keladimi? Telastinning ta'kidlashicha, bu C# konventsiyasi, garchi boshqa joydan kelgan bo'lsangiz ham, bu konventsiyani kutishingiz mumkin emas. Menga intuitiv ko'rinmaydi, yo'qolgan to'siq bo'sh emas. Men qismini, juda qismini kamdan-kam hollarda nol uchun sinov qilishim kerakligini aytdim.
qo'shib qo'ydi muallif Chris Wohlert, manba
Pedantik nuqta: nazariy jihatdan mavjud bo'lmagan to'siq bo'sh narsadir. Bo'sh to'siq bor, va mavjud bo'lmagan biron-bir to'siq emas (va, aslida, hech narsa emas, chunki u mavjud emas).
qo'shib qo'ydi muallif buhtz, manba
@ChrisWohlert: Ko'rinib turibdiki, to'plam bo'sh to'plamni o'z ichiga olishi mumkin; lekin {null} va {{}} teng bo'lishi kerakligiga ishonasiz. Bu ajoyib narsa; Men bunga hech qanday aloqasi yo'q.
qo'shib qo'ydi muallif ndsurendra, manba
@Chris Wohlert: Sizning sezgiingiz meni bezovta qiladi. Sizning fikringizcha, semantik, mavjud bo'lmagan kishi bo'sh odam, uning nomi bo'sh bo'lgan va yoshi nol va hokazo. Va sizningcha, null ni o'z ichiga olgan to'siq bo'sh to'plamni o'z ichiga olgan to'plamga mos keladi deb hisoblaysizmi (va aksincha)?
qo'shib qo'ydi muallif ndsurendra, manba
Agar null to'plamida .Add kerak bo'lsa, biz uchun ham yig'ma yarating.
qo'shib qo'ydi muallif Matthew, manba
@ChrisWohlert "semantik, mavjud bo'lmagan to'plam - bu bo'sh narsa" - Yo'q. Hech qanday mavjud bo'lmagan narsa yo'q. "Mavjud bo'lmagan to'siq" matni boshqa so'zlar bilan, masalan, ba'zi xususiyatlarga ega bo'lgan bir qator mavjud bo'lmagan narsalar bilan ishlatilishi mumkin, ammo na na uni, na boshqa so'zlar mavjud bo'lmagan to'siq haqida hech narsa deyishmaydi mavjud emas.
qo'shib qo'ydi muallif philipxy, manba
@ChrisWohlert Agar biz barcha set-teoretikni olishni istasak, (null).() Ham rostini qaytarishi kerak. Axir biz tekshirgan har bir to'plam kamida bitta elementga ega. Demak, sizda ham va haqiqiyligini qaytaradigan qo'ng'iroq bor.
qo'shib qo'ydi muallif craciun iulian, manba

Null yo'qolgan ma'lumotlarni anglatadi, element yo'q.

You might consider more broadly avoiding null — for example, use one of the built-in empty enumerables to represent a collection with no elements instead of null.

If you are returning null in some circumstances, you might change that to return the empty collection.  (Otherwise, if you're finding null's returned by library methods (not yours), that's unfortunate, and I would wrap them to normalize.)

See also https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty

23
qo'shib qo'ydi
null no elements degan ma'noni anglatmaydi, mantiqiy konventsiyani qo'llash masalasidir. Faqatgina ishlamaydi degan mahalliy OZESTRINGS haqida o'ylab ko'ring.
qo'shib qo'ydi muallif Shizam, manba
@Deduplicator, Microsoft obyektlarini bog'lash va joylashtirish haqida gapiryapsizmi? Agar siz OLE ni 90-yillardan boshlab eslayotgan bo'lsangiz! Hozirgi vaqtda ko'pgina zamonaviy tillar (C #, Java, Swift) nulllarni yo'q qilish/bartaraf etish uchun imkoniyatlarni taqdim etadi.
qo'shib qo'ydi muallif Ayyash, manba
@ErikEidt Buni qisman qilmoqdalar, chunki null "etishmayotgan ma'lumot" degani emas. null da bitta mazmunli talqinga ega emas. Buning o'rniga, bu sizga qanday munosabatda bo'lishingiz masalasidir. null ba'zan "etishmayotgan ma'lumot" uchun emas, balki "no elementlar" uchun, shuningdek, "xato ro'y berdi" yoki "boshlanmagan" yoki "ziddiyatli ma'lumotlar" yoki ba'zi bir tasodifiy, ad-hoc narsa uchun ishlatiladi .
qo'shib qo'ydi muallif ohias, manba

null-shartli sintaksikidan tashqari, ushbu muammoni bartaraf etishning yana bir usuli mavjud: o'zgaruvchan null bo'lib qoladi.

To'plamni parametr sifatida qabul qiladigan vazifani ko'rib chiqing. Agar funktsiyani amalga oshirish uchun null va bo'sh bo'lgan bo'lsa, uni boshida hech qachon null

public MyResult DoSomething(int a, IEnumerable words)
{
    words = words ?? Enumerable.Empty();

    if (!words.Any())
    {
        ...

Boshqa usullardan kollektsiyani olayotganda ham shunday qilishingiz mumkin:

var words = GetWords() ?? Enumerable.Empty();

(Agar siz GetWords va null kabi funktsiyalarni nazorat qilishingiz kerak bo'lsa, bo'sh kollektsiyaga teng bo'lsa, faqat bo'sh to'plamni birinchi joyga qaytaring .)

Endi siz har qanday operatsiyani kollektsiyangizda bajarishingiz mumkin. Bu, agar null bo'lsa, bu jarayonni bajarishingiz kerak bo'lgan juda ko'p operatsiyani bajarishingiz kerak va agar siz looping yoki so'rovlarsiz bir natija topsangiz, bu < kodi> agar shartlari to'liq bo'lsa.

13
qo'shib qo'ydi

Ushbu kodning mijozi sifatida men noto'g'ri deb hisoblayman, masalan. ((int []) bo'sh) .Any() faylni qaytarish kerakmi?

Ha, faqatgina C #-da ekanligingiz va xatti-harakatlaringiz yaxshi aniqlangan va hujjatlanganligi sababli.

Agar siz o'z kutubxonangizni tashkil qilsangiz yoki boshqa istisnosiz madaniyatga ega bo'lgan boshqa tilni ishlatayotgan bo'lsangiz, unda siz yolg'onni kutishingiz mumkin.

Shaxsan o'zimni soxta holga keltirish sening dasturingni yanada mustahkamlashtiradigan xavfsizroq yondashuv ekan, deb hisoblayman, lekin bu hech bo'lmaganda munozarali.

12
qo'shib qo'ydi
Sizning veb-so'rovingiz orqali qabul qilingan JSON hujjatidan to'ldirilgan qator mavjudligini tasavvur qiling va ishlab chiqarishda sizning API-mijozlaringizdan birida to'satdan JSON tomonidan nol qatorini seriyalashga olib keladigan qisman noto'g'ri JSON orqali yuboradigan bir muammo mavjud. kodi, eng yomoni, NULL nusha istisnosini birinchi noqonuniy so'rovni kiritgan paytdan boshlab, jurnalga kiritishda ko'rmoqchi bo'lganingiz va keyin darhol mijozlarga ularning noto'g'ri so'rovlarini tuzatishi kerakligini ayta olasiz yoki kodingiz "Oh, array empty, nothing qilmoq!" va jimgina "sotib olish savatini" bir necha hafta mobaynida JBga hech qanday narsalar yozmaganmi?
qo'shib qo'ydi muallif fenway, manba
Agar biror narsa buzilgan bo'lsa, mening kodim, boshqa bir hamkasbim yoki mijozim bo'lsin, men kodni zudlik bilan bajarib bo'lmagandim va odamlar buni aniqlab bo'lmaydigan darajada vaqtinchalik vaziyatda o'tkazganidan ko'ra bilishardi. Buni qila oladigan bo'lsak, ba'zan hashamatli va har doim ham mos emas, lekin men afzal ko'rgan yondashuv.
qo'shib qo'ydi muallif fenway, manba
Bu "mustahkamlik" ko'pincha xayolparastlikdir - agar qatorni ishlab chiqaradigan kod kutilmaganda NULLlarni kutilmagan tarzda yaratishga boshlasa, xato yoki boshqa muammolar tufayli "mustahkam" kod bu muammoni yashiradi. Bu ba'zan mos keladigan xatti-harakatlar, ammo xavfsiz emas.
qo'shib qo'ydi muallif fenway, manba
@GoatInTheMachine - Men juda ko'p narsaga rozi bo'ldim, lekin kollektsiyalar boshqalardan farq qiladi. Bo'sh kollektsiya sifatida nullni davolash juda ham qattiq yoki ajablantiradigan ish emas.
qo'shib qo'ydi muallif Telastyn, manba
@GoatInTheMachine - Men buning xavfsizligini kafolatlantirmayman, lekin siz bu muammoni yashirishni istamaysiz va bunday xatti-harakatlarning vaqti-vaqti bilan yoqimsizligini bilasiz. Mening tajribamda, muammoni yashirish (yoki boshqa kod muammolarini bartaraf etish uchun ishonchli birlik testlari) kutilmagan istisnolardan foydalanib, ilovangizni o'chirib tashlashdan yaxshiroqdir. Ya'ni, agar qo'ng'iroq kodi null-larga jo'natish uchun yetarli darajada buzilgan bo'lsa, unda istisnolarni to'g'ri bajarish imkoniyati nima?
qo'shib qo'ydi muallif Telastyn, manba

Qaytgan null tekshiruvlar sizni bezovta qilsa, o'zingizning "IsNullOrEmpty ()" kengaytmasi usuli bilan String usulini bu nom bilan aks ettirishingiz mumkin va null-check va ikkita bitta chaqiruvni bitta chaqiriqqa sarflang.

Aks holda, sizning savolingiz bo'yicha sharhning 26-sahifasida @ 17 dan keltirilgan yechim, "standart" usuldan ham qisqa va yangi null-shartli sintaksisi bilan tanish bo'lgan har bir kishi uchun juda mos keladi.

if(myCollection?.Any() == true)
10
qo'shib qo'ydi
@ jpmc26 ?? noto'g'ri, keyin myCollection ni o'qish qiyinmi? Har qanday() == rost. Gag refleksiga qaramasdan, == rost to'g'ri tekshiruvga harakat qilmoqdasiz. ?? noto'g'ri, shunchaki qo'shimcha shovqin qo'shadi va agar siz null bo'lsa, bu null == haqiqiy bajarilmasa nima sodir bo'lishini boshingizda qanday baholashni amalga oshirishingiz kerak, deyarli hatto ? .
qo'shib qo'ydi muallif Guillem Vicens, manba
Keyin u bilan rozi bo'lishga rozilik berasiz.
qo'shib qo'ydi muallif Guillem Vicens, manba
Siz ham ?? == true o'rniga xato . Bu faqat ni null holatlarini ko'rib chiqqandan keyin, bu menga aniqroq (toza) ko'rinadi va bu, aslida aniqroq emas. Booleanlar uchun == tekshiruvlari odatda mening gag refleksini tetiklaydi. =)
qo'shib qo'ydi muallif jmibanez, manba
@RyanTheLeach == aslida ishlay oladimi, deb o'ylashim kerak. Faqatgina true yoki false bo'lishi mumkin bo'lganida Boolean bilan intuitiv ravishda nima sodir bo'lganligini allaqachon bilaman; Men bu haqda o'ylamayman ham. Lekin null ni mixga tashlang va endi == to'g'ri ekanligini tekshirib ko'rishim kerak. ?? o'rniga null holini bartaraf etib, uni haqiqiy va false . Mening gag refleksiga kelsak, men buni birinchi marta ko'rganimda, darhol o'zimning ichki instinktim uni yo'q qilishdir, chunki odatda foydasiz, bu sizni istamaydi.
qo'shib qo'ydi muallif jmibanez, manba
@StevenRands: Yaxshi, rahmat.
qo'shib qo'ydi muallif Kent, manba
@ jpmc26: Men C# haqida ko'p narsa bilmayman. Nima uchun myCollection? Emasmi?() etarli emasmi?
qo'shib qo'ydi muallif Kent, manba
Men har ikkala usulda ham haqiqiy kodni yozdim (x!).() = (Haqiqiy) va (x? .Any ()? False). Keyinchalik kodni o'qishga qaytib kelganimda, ikkalasini ham (x.Any ()) o'qiganidan ko'ra o'qish qiyinlashadi, lekin ?? yolg'on, har doim meni aslida nima istayotganini hisoblash uchun to'xtatadi. Men foydalanaman ?? muammosiz hamma joyda, biroq noqonuniy ravishda uni birlashtiradigan narsa uni juda qiyin qiladi. (X!) (X) funktsiyasini tekshirishda chindan ham chalkashib ketadi! X.Any() o'rniga x.Any() o'rniga, ! = false). Ularning hech biri bir qarashda aniq emas ...
qo'shib qo'ydi muallif checksum, manba
@EricDuminil Null shartli operator ishlaydiganligi uchun myCollection? myCollection.() oddiy bir Boolean o'rniga nullable-Booleanni qaytaradi (ya'ni bool o'rniga bool?). Booldan yashirincha aylanmaydimi? bool va biz bu maxsus misolda zarur bo'lgan bool (agar if bo'lsa shartini sinab ko'rish uchun). Shuning uchun biz aniq kodni true bilan taqqoslash yoki null-coalescing operatoridan (??) foydalanishimiz kerak.
qo'shib qo'ydi muallif Steven Rands, manba

Ushbu kodning mijozi sifatida men noto'g'ri deb hisoblayman, masalan. ((int []) bo'sh) .Any() faylni qaytarish kerakmi?

Agar siz kutgan narsalar haqida o'ylayotgan bo'lsangiz, niyatlar haqida o'ylashingiz kerak.

null means something very different from Enumerable.Empty

Erik Eidtning javobida aytilganidek, null va null o'rtasidagi farq mavjud bo'sh to'plam.

Keling, ulardan qanday foydalanish kerakligini ko'rib chiqaylik.

Kitob Krzysztof Cwalina va Brad Abrams tomonidan yoziladigan Framework Design Guidelines: Conventions, Dreams, and Reusable .NET Libraries, 2nd Edition /em> quyidagi eng yaxshi amaliyoti ta'kidlaydi:

X To'plam xususiyatlarini yoki to'plamlarni qaytaradigan usullardan null qiymatlarni qaytarmasligini. Buning o'rniga bo'sh bir to'plamni yoki bo'sh qatorni qaytaring.

Consider your calling a method that is ultimately getting data from a database: If you receive an empty array or Enumerable.Empty this simply means your sample space is empty, i.e. your result is an empty set. Receiving null in this context, however, would signify an error state.

Dan Uilsonning kartoshkacha o'xshashligi bilan bir xil fikrda bo'lsa ham, sizning ma'lumotlaringiz haqida savollar berish mantiqiy bo'sh to'siq . Ammo hech qanday to'siq yo'q bo'lsa ancha kam ni keltiradi.

8
qo'shib qo'ydi
@ jpmc26: Menimcha, ushbu savolning javobi C# uchun ko'rsatma kodlash orqali boshqa ma'noga ega. Agar istasangiz, null va bo'sh bir xil bo'lgan har doim to'g'ri kodni tanlashingiz mumkin. Ba'zi hollarda siz nol yoki bo'sh bo'ladimi, xuddi shu narsani qilishingiz mumkin, ammo bu ularning bir xil ma'nosini anglatmaydi.
qo'shib qo'ydi muallif user13762, manba
Men siz aytayotgan so'zlar bilan aralashtirilishim mumkin, lekin null va bo'sh natija hosil qilish uchun munosib bo'lsa, nega siz faqat alohida foydalanmasligingizni tushunmayapsizmi va bo'sh konteyner emas, balki bir vaqtning o'zida bajaradigan usulni ularni boshqa vaziyatlarda ajratib qo'yishga ruxsat bermaydi ...
qo'shib qo'ydi muallif user13762, manba
Turli ma'nolarga ega bo'lsinmi, ular kontekstga juda bog'liq. Ko'p hollarda, mantiqiy naqadar mantiqqa to'g'ri kelishi uchun ular teng tushunchalarni ifodalaydi. har doim emas, balki tez-tez.
qo'shib qo'ydi muallif jmibanez, manba
@ Chris Va men tilni yaratgan kishilarning kodlash ko'rsatmalari sizning talablaringiz, siz foydalanadigan kutubxonalar va o'zingiz bilan ishlaydigan boshqa ishlab chiquvchilar kontekstida kodingizni baholash uchun foydalanilmaydi. Ular hech qachon kontekstda teng kelmasligi kerak, deb o'ylashadi. Ular, umuman olganda, umumiy ma'lumotlarga teng bo'lmasligi mumkin, lekin siz yozayotgan ba'zi bir funktsiyalarda natijani yaratish uchun teng bo'lishi mumkin; bu holda siz ikkalasini ham qo'llab-quvvatlash uchun kerak , lekin ular bir xil natijani ishlab chiqarilishini ta'minlaydi.
qo'shib qo'ydi muallif jmibanez, manba
@Chris Men turli kontekstlarga ega bo'lishni nazarda tutyapman (bu ko'pincha sohalarga to'g'ri keladi). Misol uchun, bir vazifani ko'rib chiqing. null va bo'sh bo'lsa, funktsiya uchun bir xil qaytarma qiymatiga olib kelishi mumkin, lekin bu null va bo'sh narsa qo'ng'iroq qilish doirasida xuddi shu narsani bildiradi degani emas.
qo'shib qo'ydi muallif jmibanez, manba

Nima uchun null va bo'sh ekanligini tushuntirib juda ko'p javoblar bor, shuning uchun ular turli xil yoki muomala qilish kerak emas, nima uchun tushuntirishga harakat qiladigan turli xil va yetarli fikrlar. Biroq siz:

Ushbu kodning mijozi sifatida men noto'g'ri deb hisoblayman, masalan. ((int []) bo'sh) .Any() faylni qaytarish kerakmi?

Bu juda oqilona kutish . Siz boshqalar tomonidan mavjud xatti-harakatni himoya qilgan holda, siz o'ng sifatida ish tutasiz. Men joriy dastur falsafasiga rozi bo'lyapman, lekin haydash omillari faqatgina kontekstdan tashqarida emas.

Given that Any() without predicate is essentially Count() > 0 then what do you expect from this snippet?

List list = null;
if (list.Count > 0) {}

Yoki umumiy:

List list = null;
if (list.Foo()) {}

NullReferenceException kutasizmi deb o'ylayman.

  • Any() is an extension method, it should smoothly integrate with the extended object then throwing an exception is the least surprising thing.
  • Not every .NET language supports extension methods.
  • You can always call Enumerable.Any(null) and there you definitely expect ArgumentNullException. It's the same method and it has to be consistent with - possibly - almost EVERYTHING else in the Framework.
  • Accessing a null object is a programming error, framework should not enforce null as magic value. If you use it that way then it's your responsibility to deal with it.
  • It's opinionated, you think one way and I think another way. Framework should be as much unopinionated as possible.
  • If you have a special case then you must be consistent: you have to take more and more highly opinionated decisions about all the other extension methods: if Count() seems an easy decision then Where() is not. What about Max()? It throws an exception for an EMPTY list, shouldn't it throw also for a null one?

LINQ dasturidan avval null bir joriy qiymati (masalan, String.IsNullOrEmpty() ) bo'lsa) aniq uslublarni joriy qilish uchun qanday kutubxonachilar yaratgan bo'lsa, ular HAD mavjud dizayn falsafasiga mos keladigan bo'lishi kerak. Ya'ni, yozish uchun juda ham ahamiyatsiz bo'lsa ham, EmptyIfNull() va EmptyOrNull() ning ikkita usuli foydalidir.

3
qo'shib qo'ydi

Jim har bir sumkada kartoshkani qoldirishi kerak. Aks holda men uni o'ldiraman.

Jimda beshta kartoshka bo'lgan sumka bor. Kartochkada .Any() kartoshka bormi?

"Yes," you say. <= true

Shunday qilib, Jim bu safar yashaydi.

Jim barcha kartoshkani olib, ularni yutadi. U erda? Kartoshkada biron bir kartoshka bormi?

"No," you say. <= false

Jimni o'ldirish vaqti.

Jim to'liq sumkani yong'inga tashlaydi. U erda mavjudmi? Qandagi kartoshkadan har qanday narsa bormi?

"There is no bag." <= ArgumentNullException

Should Jim live or die? Well we didn't expect this so I need a ruling. Is letting Jim get away with this a bug or not?

Siz hech qanday noqonuniy shenanigans bilan shu tarzda harakat qilmaganingizni bildirish uchun izohlarni ishlatishingiz mumkin .

public bool Any( [NotNull] List bag ) 

Lekin sizning asboblaringiz zanjiri uni qo'llab-quvvatlashi kerak. Demak, siz hali ham yozma tekshiruvlarni yakunlaysiz.

1
qo'shib qo'ydi

Menimcha, bu erda muhim nuqta, istisno qilish o'rniga noto'g'ri yo'lni qaytarib, sizning kodingizning kelajakdagi o'qiydiganlari/modifikatorlari bilan bog'liq bo'lishi mumkin bo'lgan ma'lumotlarni bekor qilishdir.

Ro'yxatning bo'sh bo'lishi mumkin bo'lsa, men buning uchun alohida mantiqiy yo'lga ega bo'lishni tavsiya qilaman, aks holda kelajakda ba'zi bir ro'yxatga asoslangan mantiqni (masalan, qo'shimchani) boshqasining {} ga kiritishingiz mumkin, natijada istalmagan istisno, ularning taxmin qilish uchun asoslari yo'q edi.

O'qish qobiliyati va parvarish qilish har doim "qo'shimcha shart" yozishim kerak.

0
qo'shib qo'ydi

Agar bu sizni bezovta qiladigan bo'lsa, oddiy kengaytma usulini taklif qilaman.

static public IEnumerable NullToEmpty(this IEnumerable source)
{
    return (source == null) ? Enumerable.Empty() : source;
}

Endi buni qilishingiz mumkin:

List list = null;
var flag = list.NullToEmpty().Any( s => s == "Foo" );

... va bayroq false ga o'rnatiladi.

0
qo'shib qo'ydi
Bu so'ralgan savolga javob bermaydi.
qo'shib qo'ydi muallif Not Joe Bloggs, manba
@ KennethK.but taqdim etilgan muammoni hal qilish uchun ko'rinadi.
qo'shib qo'ydi muallif NirIzr, manba
return ifodasini yozing: return source? Enumerable.Empty ();
qo'shib qo'ydi muallif Amida, manba

Umumiy qoida sifatida kodni ko'pini yozaman, da'vat qiluvchi menga nol ma'lumot bermasligi uchun mas'uldir, asosan Null uchun yo'q deb ayting (va shunga o'xshash boshqa xabarlar). Null tushunchasi odatda yaxshi tushunchaga ega emas va shuning uchun o'zingizning parametrlarni ilgarigidek amaliy ishga solishingiz kerak. O'rtacha API bilan ishlayapsiz deb hisoblasangiz, siz hech qachon null qiymatni qaytarib olmaysiz, shuning uchun nullni tekshirishingiz shart emas. Nol nuqtasi, boshqa javoblar kabi, davom etishdan oldin ishlash uchun sizda mavjud bo'lgan ob'ektga (masalan, "sumka") ega bo'lishingiz kerak. Bu Any xususiyati emas, balki uning o'rniga tilining o'ziga xos xususiyati. . Ko'p operatsiyalarni bo'sh ob'ektda bajarolmaysiz, chunki u mavjud emas. Men mashinamda do'konga borishingizni so'rasam, xuddi men mashinamga ega emasman, shuning uchun mashinamni do'konga olib borish uchun hech qanday imkoniyat yo'q. Tugatilmagan narsa haqida operatsiya qilish noqonuniydir.

Noldan foydalanish uchun amaliy holatlar mavjud, masalan siz so'ragan ma'lumotlarga ega bo'lmasangiz (masalan, mening yoshim nima ekanini so'rasam, bu erda javob berishingiz mumkin bo'lgan eng tanlov "bilmayman" ", Null qiymati bu). Biroq, aksariyat hollarda siz o'zingizning o'zgaruvchilaringiz ishga tushirilganligini yoki yo'qligini bilishingiz kerak. Va agar qilmasangiz, kodingizni tortib olishingiz kerakligini tavsiya qilaman. Har qanday dasturda yoki funktsiyada bajaradigan birinchi narsa, uni ishlatishdan oldin qiymatni ishga tushirishdir. Null qiymatlarni tekshirishim kerakligi kamdan-kam hollarda, chunki men o'z parametrlarga ega bo'lmaganligimni kafolatlay olaman. O'zingizning o'zgaruvchan vositalarni ishga tushirish uchun yaxshi odat bo'lib, siz qanchalik tez-tez nulllarni tekshirishingiz kerak.

0
qo'shib qo'ydi

Bu C# kengaytmasi usullari va ularning dizayn falsafasi haqidagi savoldir, shuning uchun bu savolga javob berishning eng yaxshi usuli MSDN kengaytma usullari bo'yicha hujjatlari :

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C#, F# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance.

When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.

If you do implement extension methods for a given type, remember the following points:

  • An extension method will never be called if it has the same signature as a method defined in the type.
  • Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive.

Xulosa qilish uchun, kengaytma usullari, ishlab chiquvchilar buni to'g'ridan-to'g'ri qila olmasalar ham, muayyan turdagi namuna usullarini qo'shish uchun mo'ljallangan. Masalaning usullari, agar mavjud bo'lsa, har doim kengaytmasi usullarini bekor qiladi (agar bu metod metodikasi sintaksisi ishlatilganda), to'g'ridan-to'g'ri metodni qo'shmasangiz yoki sinfni kengaytira olmasangiz, bu faqat faqat *.

Boshqacha qilib aytganda, kengaytma usuli bir misol usuli kabi harakat qilish kerak, chunki u ba'zi bir mijoz tomonidan bir misol usuliga aylanishi mumkin. Va shunga qaramay, uni chaqirishni boshlagan ob'ekt null bo'lsa, u holda kengaytma usuli bo'lishi kerak.


*As a side note, this is exactly the situation that the designers of LINQ faced: when C# 3.0 was released, there were already millions of clients that were using System.Collections.IEnumerable and System.Collections.Generic.IEnumerable, both in their collections and in foreach loops. These classes returned IEnumerator objects which only had the two methods Current and MoveNext, so adding any additional required instance methods, such as Count, Any, etc., would be breaking these millions of clients. So, in order to provide this functionality (especially since it can be implemented in terms of Current and MoveNext with relative ease), they released it as extension methods, which can be applied to any currently existing IEnumerable instance and can also be implemented by classes in more efficient ways. Had C#'s designers decided to release LINQ on day one, it would have been provided as instance methods of IEnumerable, and they probably would have designed some kind of system to provide default interface implementations of those methods.

0
qo'shib qo'ydi