Keyinroq tekshiruvlar uchun C # -ga nolli chekni kiritish kerakligini olib tashlashning usullari bormi?

Men turli xil kombinatsiyalarni sinab ko'rdim, lekin bu taqqoslash uchun ishlashim mumkin bo'lgan yagona birikma edi! "=" "Null uchun muammo tug'dirdi:

        if (options.English != null && options.English != "")
        {
            if (options.English.StartsWith("^"))
            {
                query = query.Where(w => w.English.StartsWith(options.English.Trim().Substring(1)));
            }
            else
            {
                query = query.Where(w => w.English.Contains(options.English.Trim()));
            }
        }

Buni optimallashtiradigan narsa bormi, agar uni bitta yoki ikkita bo'lsa, ikkinchisining tashqi va ichki if ixtiyoriga ega bo'lishdan ko'ra bir-birini ta'qib qilgan so'zlarni soddalashtirishi mumkin.

1
@maxshuty: Siz muammo emas ( options == null ) bo'lsa-da, faqatgina options.English haqida savol tug'iladi.
qo'shib qo'ydi muallif Ben Voigt, manba
qo'shib qo'ydi muallif Ðаn, manba
Sizda uchta holat bor: StartsWith, Contains, va na. Uch holatda ikkita shartni ajratish kerak.
qo'shib qo'ydi muallif Michael Liu, manba
@Anne ushbu havolani ko'ring: msdn.microsoft.com /en-us/library/hh925568(v=vs.110).aspx va keyin ni tanlashingiz mumkin .English
qo'shib qo'ydi muallif maxshuty, manba
Siz C# 6 dan foydalanasizmi? Null tarqalishni ko'rishni xohlashingiz mumkin, siz butun tekshiruvdan qutulishingiz mumkin.
qo'shib qo'ydi muallif maxshuty, manba
@Maxshuty Men so'nggi VS2015 emasman, lekin C# yoki emas, balki ishonch emas. Buni qanday tekshirishim mumkinligini bilasizmi va agar u 6.0 bo'lsa kod qanday o'zgartirilishi mumkin?
qo'shib qo'ydi muallif user1464139, manba
String.IsNullOrEmpty() ni sinab ko'rdingizmi?
qo'shib qo'ydi muallif Cisco Cabe, manba

6 javoblar

Siz string.IsNullOrEmpty() ni qidirasiz.

Ichki joyni olib tashlash uchun (C # 6)

if (options.English?.StartsWith("^") == true) {
    ...
} else if (!string.IsNullOrEmpty(options.English) {
    ...
}
4
qo'shib qo'ydi
@radarbob Natijani endi o'zgartirdi. OP kodida 3 kodli yo'l bor va faqat sizning ikkita varaq.
qo'shib qo'ydi muallif Servy, manba
@SLaks Sizning kodingiz endi OP kodiga teng emas, shuningdek agar bo'lsa ifodalarini kiritadi.
qo'shib qo'ydi muallif Servy, manba
Agar so'rayotgan bo'lsa, bu if bo'lsa so'zlarini olib tashlamaydi
qo'shib qo'ydi muallif Servy, manba
@Servy: O'zgartirishni ko'ring.
qo'shib qo'ydi muallif SLaks, manba
Anna: Uzr; siz == true yoki ?? null ni chiqarib tashlashni bildirgan.
qo'shib qo'ydi muallif SLaks, manba
Xato olaman: CS0266 "Bool" turini notekis ravishda aylantira olmaydi. "Bool" ga. Biron bir konvertatsiya mavjud (bir dovoni etishmayapsizmi?) Birinchi satrda opsiyalarni sinab ko'rdim. Ingliz tili? Boshlang'ichSayt ("^"))
qo'shib qo'ydi muallif user1464139, manba
Rahmat, men bu chekni bilmasdim va hech bo'lmaganda men buni qilishga harakat qiladigan narsalarni biroz aniqroq qilar edim.
qo'shib qo'ydi muallif user1464139, manba

Agar ichki if ni boshqa joyga kiritmasdan, unchalik katta bo'lmagan zanjirga aylantirmaslik muhim ahamiyatga ega.

if (A) {
    if (B) { ... }
}

bo'ladi

if (!A)
{ /* do nothing */ }
else if (B) { ... }

Sizning holatingizda shunday

if (string.IsNullOrEmpty(options.English))
    { /* do nothing */ }
else if (options.English.StartsWith("^"))
    {
        query = query.Where(w => w.English.StartsWith(options.English.Trim().Substring(1)));
    }
else
    {
        query = query.Where(w => w.English.Contains(options.English.Trim()));
    }

Til qoidalariga ko'ra, if (B) ... else aslida birinchi bo'lib ichki qismga kiritilgan bo'lsa-da, lekin inson dasturchilari uni uyma-joy sifatida emas, balki zanjir .

3
qo'shib qo'ydi
@Servy: else ichidagi joylashtirish programlovchilar uchun yaxshiroqdir, chunki zanjir haqida o'ylash daraxt haqida o'ylashdan osonroqdir. Derivator zanjirni saqlash uchun daraxt qurayotganiga qaramay, zanjirning kontseptual modeli hali ham ishlaydi .
qo'shib qo'ydi muallif Ben Voigt, manba
@Anne: Yo'q, uch xil yo'lni topishingiz kerak, shuning uchun bu juda oson. Maykl Liu allaqachon sharhni qoldirgan edi, shuning uchun uni takrorlashdan bezovta bo'lmadim.
qo'shib qo'ydi muallif Ben Voigt, manba
@Servy: Bu OP so'radi (ikkita agar bir-birini ta'qib qilayotgan bo'lsa). U oddiygina zanjirning derleyici nuqtai nazaridan hali ham yuvalanmadığını tushunmadi. Agar u bu haqda boshqacha fikrda bo'lsa, bu uni aylantirish uchun yaxshi asosdir.
qo'shib qo'ydi muallif Ben Voigt, manba
@Servy: Birinchi agar qaytish, yoki break; bo'lishi mumkin bo'lsa, else qolganlari kerak bo'lmaydi. Biz ko'rsatilmaydigan kodning atrofdagi tuzilishiga bog'liq. Ammo agar bu zanjir kontseptual ravishda ketma-ketlikda ko'rib chiqilsa, uxlash jarayoni kompilyatsiya jarayonining asaridir va uni o'ylashning foydali usulidir.
qo'shib qo'ydi muallif Ben Voigt, manba
Agar agar so'zlari ichki o'rnatilgan bo'lishi uchun yaxshi bo'lsa, unda bu savolga javob berish uchun hech qanday sabab yo'q (bu bilan izohda o'rinli narsa), ammo bu hali hammasi emas savolga javob berishni istasangiz, ularni agar so'zlari bo'lsa, uni saqlamasdan emas, balki joylashtirish kerak deb o'ylaysiz.
qo'shib qo'ydi muallif Servy, manba
Ammo agar ifodasi boshqa bo'lmasa. U ichki qismida joylashgan.
qo'shib qo'ydi muallif Servy, manba
Shunday qilib, siz aytganidek hali ham bo'lsa, so'zlari kiritilgan bo'lsa, u holda bo'lsa, ga qo'shimcha ravishda u erda faqat bosh karıştırıcı bo'sh blok bor > bayonotlar.
qo'shib qo'ydi muallif Servy, manba
@Anne No, ushbu izoh sizga mos keladigan vaziyatga mos kelishini o'ylab, noto'g'ri edi, chunki unga teng bo'lmagan kod berilgan edi.
qo'shib qo'ydi muallif Servy, manba
@BenVoigt - Sharhlardan biri C# 6.0 ga tegishli edi. Menimcha (VS2015 ning so'nggi versiyasi). Buning javobini soddalashtirmoqchi bo'ladimi?
qo'shib qo'ydi muallif user1464139, manba

Kodni o'z usuliga qaytaradigan bo'lsangiz, u holda return iborasini qo'llashingiz mumkin, agar agar bo'lsa so'zlari ularni joylashtirmasdan:

public static IEnumerable AddOption(IEnumerable query, Option options)
{
    if (string.IsNullOrEmpty(options.English))
        return query;
    if (options.English.StartsWith("^"))
        return query.Where(w => w.English.StartsWith(options.English.Trim().Substring(1)));
    return query = query.Where(w => w.English.Contains(options.English.Trim()));
}

So'ngra siz ko'rsatgan usulga query = AddOptions (so'rovlar, variantlar) yozishingiz mumkin.

2
qo'shib qo'ydi
Birovning fikrini javobga aylantirganda, kredit berish o'rinli bo'ladi.
qo'shib qo'ydi muallif Ben Voigt, manba
@BenVoigt Men hech kimning fikriga javob bermadim. Mening javobimni yozayotganimda siz ham shunga o'xshash taklif bilan sharh yozgansiz.
qo'shib qo'ydi muallif Servy, manba

If all you're trying to do is remove the nested ifs, then you can store the lambdas in a Dictionary

var lookup = new Dictionary>() {
    { true, w => w.English.StartsWith(options.English.Trim().Substring(1)) },
    { false, w => w.English.Contains(options.English.Trim())} };

if (options.English != null && options.English != "")
{
    query = query.Where(lookup[options.English.StartsWith("^")]);
}

Endi, noreferrer"> String.IsNullOrEmpty() bilan birga ?: siz buni bir bayonotga tushirishingiz mumkin ... va hatto dahshatli emas:

query = String.IsNullOrEmpty(options.English) ?
    query : query.Where(lookup[options.English.StartsWith("^")]);

Biroq, sizda faqat ikkita variant borligini hisobga olgan holda Lug'at , albatta, zarur emas, faqat bir nechta mahalliy aholi foydalaning:

Func startsWithCaret = w => w.English.StartsWith(options.English.Trim().Substring(1));
Func doesNotStartWithCaret = w => w.English.Contains(options.English.Trim());
var lambda = options.English.StartsWith("^") ? startsWithCaret : doesNotStartWithCaret;

Siz aytganingiz endi

query = String.IsNullOrEmpty(options.English) ? query : query.Where(lambda);

bo'lsa bo'lmasa! :-)

0
qo'shib qo'ydi
Men tekshirish usullari haqida ishonchim komil emas. Men Entity Framework va SQL Server dan foydalanmoqdaman. Sizningcha, bu EF bilan ishlaydi deb o'ylaysizmi?
qo'shib qo'ydi muallif user1464139, manba

Sizning fikringiz soddalashtirilishi mumkin:

        if (!string.IsNullOrEmpty(options.English))
        {
            var s = options.English.Trim(); 
            query = query.Where(w => { return s.StartsWith("^") ? 
                w.English.StartsWith(s.Substring(1)) : w.English.Contains(s); });
        }
0
qo'shib qo'ydi

Eng kam ishni bajaruvchi emas, balki, eng kamida, agar null uchun bo'lsa, eng qisqa yo'l bo'lishi mumkin

if (!options.English.IsNullOrEmpty())
    query = query.Where(w =>
        w.English.Contains(string.Concat("^", options.English)
        .Replace("^^","^").Substring(1).Trim()));

Faqat ^ ^/ bilan ^ ^ kodini o'zgartiring (ehtimol, ^ ) va keyin har doim Substring 1).

0
qo'shib qo'ydi