CodeGym /Kurslar /C# SELF /Funksiyadan bir neçə dəyərin qaytarılması: out-parametrlə...

Funksiyadan bir neçə dəyərin qaytarılması: out-parametrlər və körtəjlər

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Təsəvvür elə ki, bizdə bir funksiya var, hansı ki, istifadəçi barədə (məsələn, adı ilə) həm yaşını, həm qeydiyyat tarixini, həm də aktivlik flag-ını qaytarmalıdır. C və C#-ın köhnə versiyalarında normal sayılırdı ki, funksiya yalnız bir dəyər qaytarsın. Bəs birdən çox dəyər lazımdırsa, nə edək? Bu sual müxtəlif yanaşmaların yaranmasına səbəb oldu və hər birinin öz üstün və çatışmaz tərəfləri var.
Əvvəlki mühazirələrdə artıq körtəjlərlə tanış olmuşduq. İndi isə out-parametrləri öyrənəcəyik və bu iki yanaşmanı müqayisə edəcəyik.

Ən məşhur yanaşmalar:

  • out-parametrlərdən istifadə etmək.
  • Lazım olan sahələri olan bir obyekt qaytarmaq (anonim tip və ya öz class-ın).
  • Körtəj (ValueTuple) qaytarmaq.

Bu mühazirədə biz bu yanaşmalardan ikisini — out-parametrləri və körtəjləri — ətraflı baxacağıq və onları "üz-üzə" müqayisə edəcəyik ki, funksiyadan bir neçə dəyər qaytarmaq üçün hansının daha yaxşı olduğunu anlayaq.

2. out-parametrlər: keçmişdən salam

Belə bir funksiya görəndə:


void GetUserInfo(string userName, out int age, out DateTime registrationDate, out bool isActive)
{
    // burada hesablamalar
    age = 42;
    registrationDate = new DateTime(2010, 1, 1);
    isActive = true;
}

adamın ağlına gəlir: bu funksiya yoxsa kiçik bir avtoyuma filialıdır? Hər şey çölə qaytarılır, əsas qaytarılan dəyərdən kənarda!

Necə işləyir

Çağıran kod əvvəlcədən dəyişənləri elan etməlidir ki, funksiya onları doldursun:

int age;
DateTime reg;
bool isActive;

GetUserInfo("Bob", out age, out reg, out isActive);

// İndi bütün dəyişənlər doludur
Console.WriteLine($"{age}, {reg}, {isActive}");

out-yanaşmasının mənfi cəhətləri

  • Oxumaq çətindir: Metodun signaturası çox uzanır, qaytarılan məlumatların mənası həmişə parametr adlarından aydın olmur.
  • Chain-lərdə narahatlıq: Belə metodu rahatlıqla chain-ə (məsələn, nəticəni birbaşa başqa metoda ötürmək) daxil etmək olmur.
  • Dəyişənləri dəyişir: Metod mövcud dəyişənləri dəyişməlidir; əgər out-u unutsaq — compile səhvi olacaq.
  • İlkinləşdirmədə gecikmə: Compiler məcbur edir ki, xarici dəyişənləri elan edəsən, hətta nəticəni bir dəfə istifadə etmək istəsən belə.
  • Böyük metodlarda oxunaqlılıq zəifdir: Əgər out-parametrlər çoxdursa, asanlıqla qarışdırmaq olar ki, nə nə üçündür və hansı ardıcıllıqla gedir.

Bax, burada körtəjlərin ulduz kimi parladığı yer gəlir.

3. Körtəjlər — yanaşmanın təkamülü

Nümunədə müqayisə edək

Körtəj ilə:


public (int Age, DateTime RegistrationDate, bool IsActive) GetUserInfo(string userName)
{
    // bazada axtarışın emulyasiyası
    return (42, new DateTime(2010, 1, 1), true);
}

İstifadəsi:

// Bütün dəyərləri birbaşa alırıq və dəyişənlərə ad veririk
var (age, regDate, isActive) = GetUserInfo("Bob");
Console.WriteLine($"{age}, {regDate}, {isActive}");

Artıq elanlar yoxdur, out yoxdur, hər şey maksimum oxunaqlıdır!

Müqayisə cədvəli: out vs tuple

Kriteriya Out-parametrlər Körtəjlər (ValueTuple)
Signatura uzun, out-parametrlər siyahıda kompakt, hər şey bir "bağlama" ilə qaytarılır
İstifadə dəyişənləri elan etmək, sonra metodu çağırmaq lazımdır birbaşa deconstruct etmək olar
Oxunaqlılıq əgər bir neçə out-parametr varsa, tez-tez itir elementlərin adları dərhal aydındır
Asan kombinə etmək? yox bəli, iç-içə və ötürmək olar

Körtəjlər VS. out — qapağın altında nə baş verir

out-parametrlərlə funksiya əslində öz "ərazisindən" kənarda olan yaddaşla işləyir: bir az sadələşdirsək, o, başqa yerdə yaradılmış dəyişənləri dəyişir. Bu, diqqət tələb edir, çünki təsadüfən dəyişənlərin vəziyyətini "çirkləndirə" bilərsən (compiler-ə təşəkkürlər ki, məcburi mənimsəmə var!).

Körtəj isə — funksiya tərəfindən yaradılan, tam initializasiya olunan və çölə qaytarılan data strukturudur. Yəni, hər şey — bir bağlama, onu yolda itirməyəcəksən və unutmayacaqsan.

Kodun oxunması və dəstəklənməsi

Razılaş ki, bir həftə sonra başqasının koduna baxanda belə görmək istəyirsən:

(var age, var city, var isActive) = GetUserInfo("Anna");

yoxsa

int age;
string city;
bool isActive;
GetUserInfo("Anna", out age, out city, out isActive);

Körtəjlər metodların signaturasını daha az "səs-küylü" edir və istifadənin nəticəsi — intuitiv aydın olur.

4. Körtəjlərin xüsusilə yaxşı olduğu situasiyalar

1. Nəticə və error mesajı qaytarmaq lazım olanda

public (bool Success, string ErrorMessage) TryProcess(string data)
{
    if (string.IsNullOrEmpty(data))
        return (false, "Məlumat yoxdur");

    // məlumatların işlənməsi...
    return (true, "");
}

var (ok, error) = TryProcess(input);
if (!ok)
    Console.WriteLine($"Xəta: {error}");

2. Bir neçə axtarış nəticəsi qaytaran funksiyalar üçün

public (User? FoundUser, int Index) FindUserByName(User[] users, string name)
{
    for (int i = 0; i < users.Length; i++)
    {
        if (users[i].Name == name)
            return (users[i], i);
    }
    return (null, -1);
}

3. “Cüt” dəyərlər üçün: minimum və maksimum hesablanması

public (int min, int max) FindMinMax(int[] numbers)
{
    int min = numbers[0], max = numbers[0];
    foreach (var n in numbers)
    {
        if (n < min) min = n;
        if (n > max) max = n;
    }
    return (min, max);
}

var (minValue, maxValue) = FindMinMax(arr);
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION