18-bo‘lim

Generiklar va Nothing xavfsizligi

Of T bilan universal sinf va funksiya yozish, cheklovlar, Nullable qiymat turlari va NullReferenceException dan qochish.

🕑 11 daqiqa o‘qish 📄 580 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Generik funksiya
  2. Generik sinf
  3. Cheklovlar
  4. Nothing muammosi
  5. Nullable qiymat turlari
  6. 0 va "qiymat yo'q" farqi
  7. Zaxira qiymat
  8. Generik va Nullable birga
  9. Xulosa

Generik - tur nomini keyinroq aytishga imkon beradigan yozuv. List(Of String) va List(Of Integer) - bitta sinfning ikki ko'rinishi.

Generik funksiya #

VB
Module Dastur
    Function Almashtir(Of T)(ByRef a As T, ByRef b As T)
        Dim vaqtinchalik As T = a
        a = b
        b = vaqtinchalik
    End Function

    Sub Main()
        Dim x As Integer = 10, y As Integer = 20
        Almashtir(x, y)
        Console.WriteLine($"{x}, {y}")

        Dim m As String = "birinchi", n As String = "ikkinchi"
        Almashtir(m, n)
        Console.WriteLine($"{m}, {n}")
    End Sub
End Module
Natija
20, 10
ikkinchi, birinchi

Bitta funksiya - ikkala tur uchun. T - shunchaki nom, uning o'rniga har qanday tur kelishi mumkin.

Nega Object ishlatmaymiz

Object ham har qanday turni saqlaydi. Lekin unda ikki muammo bor:

  1. Qiymatni qaytarib olish uchun har safar aylantirish kerak va xato turni yozsangiz, xato dastur ishlayotganda chiqadi.
  2. Qiymat turlari (Integer kabi) "quti"ga solinadi va bu sekin.

Generik esa turni kompilyatsiya paytida biladi: xato oldin topiladi va qo'shimcha ish bajarilmaydi.

Generik sinf #

VB
Public Class Quti(Of T)
    Private _elementlar As New List(Of T)

    Public Sub Solish(element As T)
        _elementlar.Add(element)
    End Sub

    Public Function Olish(indeks As Integer) As T
        Return _elementlar(indeks)
    End Function

    Public ReadOnly Property Soni As Integer
        Get
            Return _elementlar.Count
        End Get
    End Property
End Class

Module Dastur
    Sub Main()
        Dim sonlar As New Quti(Of Integer)
        sonlar.Solish(10)
        sonlar.Solish(20)
        Console.WriteLine($"{sonlar.Soni} ta, birinchisi {sonlar.Olish(0)}")

        Dim ismlar As New Quti(Of String)
        ismlar.Solish("Malika")
        Console.WriteLine($"{ismlar.Soni} ta, birinchisi {ismlar.Olish(0)}")
    End Sub
End Module
Natija
2 ta, birinchisi 10
1 ta, birinchisi Malika

Cheklovlar #

Ba'zan T dan biror narsani talab qilish kerak:

VB
Module Dastur
    Function Kattasi(Of T As IComparable(Of T))(a As T, b As T) As T
        If a.CompareTo(b) >= 0 Then
            Return a
        End If
        Return b
    End Function

    Sub Main()
        Console.WriteLine(Kattasi(15, 42))
        Console.WriteLine(Kattasi("olma", "anor"))
        Console.WriteLine(Kattasi(3.7, 2.1))
    End Sub
End Module
Natija
42
olma
3.7

As IComparable(Of T) - "T solishtirila oladigan tur bo'lishi shart" degani. Usiz CompareTo ni chaqirib bo'lmasdi.

CheklovMa'nosi
As ClassHavola turi bo'lishi shart
As StructureQiymat turi bo'lishi shart
As NewParametrsiz konstruktori bo'lishi shart
As IBirorShu interfeysni bajarishi shart
As {Class, New}Bir nechta shart
VB
Public Class Omborxona(Of T As {Class, New})
    Public Function Yangi() As T
        Return New T()
    End Function
End Class

Public Class Hujjat
    Public Property Nom As String = "yangi hujjat"
End Class

Module Dastur
    Sub Main()
        Dim o As New Omborxona(Of Hujjat)
        Dim h As Hujjat = o.Yangi()
        Console.WriteLine(h.Nom)
    End Sub
End Module
Natija
yangi hujjat

As New cheklovi bo'lmasa, New T() yozib bo'lmaydi - kompilyator T da konstruktor borligini bilmaydi.

Nothing muammosi #

VB
Module Dastur
    Function Topish(royxat As List(Of String), qidiruv As String) As String
        For Each s As String In royxat
            If s = qidiruv Then
                Return s
            End If
        Next
        Return Nothing
    End Function

    Sub Main()
        Dim royxat As New List(Of String) From {"olma", "anor"}

        Dim topildi As String = Topish(royxat, "uzum")
        Console.WriteLine(topildi Is Nothing)

        If topildi IsNot Nothing Then
            Console.WriteLine(topildi.ToUpper())
        Else
            Console.WriteLine("Topilmadi")
        End If
    End Sub
End Module
Natija
True
Topilmadi
NullReferenceException - eng ko'p uchraydigan xato

Agar yuqoridagi tekshiruvsiz topildi.ToUpper() deb yozsangiz, dastur NullReferenceException bilan to'xtaydi.

Bu dunyodagi eng ko'p uchraydigan dastur xatosi. Undan qochishning uch yo'li:

  1. Har doim IsNot Nothing bilan tekshirish.
  2. Nothing qaytarmaslik - bo'sh ro'yxat yoki bo'sh satr qaytarish.
  3. If(qiymat, zaxira) bilan zaxira qiymat berish.

Nullable qiymat turlari #

Integer hech qachon bo'sh bo'lolmaydi - uning standart qiymati 0. Lekin "qiymat kiritilmagan" holatini ko'rsatish kerak bo'lsa-chi?

VB
Module Dastur
    Sub Main()
        Dim ball As Integer? = Nothing
        Console.WriteLine(ball.HasValue)
        Console.WriteLine(ball.GetValueOrDefault())
        Console.WriteLine(ball.GetValueOrDefault(-1))

        ball = 88
        Console.WriteLine(ball.HasValue)
        Console.WriteLine(ball.Value)
    End Sub
End Module
Natija
False
0
-1
True
88

Integer? - bu Nullable(Of Integer) ning qisqa yozuvi.

A'zoNima qiladi
HasValueQiymat bormi
ValueQiymatni oladi (bo'lmasa xato)
GetValueOrDefault()Bo'lmasa turning standart qiymati
GetValueOrDefault(x)Bo'lmasa x

0 va "qiymat yo'q" farqi #

VB
Module Dastur
    Sub Korsat(nom As String, ball As Integer?)
        If ball.HasValue Then
            Console.WriteLine($"{nom}: {ball.Value} ball")
        Else
            Console.WriteLine($"{nom}: imtihon topshirmagan")
        End If
    End Sub

    Sub Main()
        Korsat("Malika", 88)
        Korsat("Husanboy", 0)
        Korsat("Nodira", Nothing)
    End Sub
End Module
Natija
Malika: 88 ball
Husanboy: 0 ball
Nodira: imtihon topshirmagan

Mana nima uchun Integer? kerak: 0 ball olgan talaba bilan imtihonga kelmagan talaba - butunlay boshqa holatlar. Oddiy Integer bilan ularni ajratib bo'lmaydi.

Zaxira qiymat #

VB
Module Dastur
    Sub Main()
        Dim kiritilgan As String = Nothing
        Console.WriteLine(If(kiritilgan, "noma'lum"))

        Dim ball As Integer? = Nothing
        Console.WriteLine(If(ball, 0))

        Dim royxat As List(Of String) = Nothing
        Dim xavfsiz = If(royxat, New List(Of String))
        Console.WriteLine(xavfsiz.Count)
    End Sub
End Module
Natija
noma'lum
0
0

If(a, b) - "a bor bo'lsa a, yo'q bo'lsa b". Eng qisqa va eng xavfsiz shakl.

Nothing qaytarmaslikka harakat qiling

Funksiya ro'yxat qaytarishi kerak bo'lsa, hech narsa topilmaganda Nothing emas, bo'sh ro'yxat qaytaring.

Shunda chaqiruvchi tekshirmasdan For Each qila oladi - bo'sh ro'yxat bo'ylab yurish xato bermaydi, shunchaki hech narsa bajarilmaydi.

Bu kichik odat NullReferenceException larning yarmini yo'q qiladi.

Generik va Nullable birga #

VB
Module Dastur
    Function XavfsizOrtacha(sonlar As List(Of Integer)) As Double?
        If sonlar Is Nothing OrElse sonlar.Count = 0 Then
            Return Nothing
        End If
        Return sonlar.Average()
    End Function

    Sub Main()
        Dim toliq As New List(Of Integer) From {80, 90, 100}
        Dim bosh As New List(Of Integer)

        Dim a As Double? = XavfsizOrtacha(toliq)
        Dim b As Double? = XavfsizOrtacha(bosh)

        Console.WriteLine(If(a.HasValue, a.Value.ToString(),
                             "hisoblab bo'lmadi"))
        Console.WriteLine(If(b.HasValue, b.Value.ToString(),
                             "hisoblab bo'lmadi"))
    End Sub
End Module
Natija
90
hisoblab bo'lmadi

Bo'sh ro'yxatning o'rtachasi mavjud emas - 0 ham noto'g'ri javob bo'lardi. Double? aynan shuni ifodalaydi.

Amaliy topshiriq
  1. Ikkita qiymatni almashtiruvchi generik funksiya yozing.
  2. Quti(Of T) sinfini Double bilan sinang.
  3. Ro'yxatdagi eng kattasini topadigan generik funksiya yozing.
  4. As New cheklovi bilan obyekt yasovchi sinf yarating.
  5. Cheklovni olib tashlab, xatoni o'qing.
  6. Nothing qaytaradigan funksiya yozib, uni xavfsiz chaqiring.
  7. Integer? bilan "kiritilmagan" holatini ifodalang.
  8. GetValueOrDefault(-1) ni sinab ko'ring.
  9. If(qiymat, zaxira) bilan bo'sh ro'yxatni almashtiring.
  10. Bo'sh ro'yxatning o'rtachasini Double? bilan qaytaring.

Xulosa #

  • Of T - turni keyinroq aytish imkoni; Object dan tez va xavfsizroq.
  • Cheklovlar (As Class, As New, As IComparable(Of T)) T dan nimani talab qilishni belgilaydi.
  • NullReferenceException - eng ko'p uchraydigan xato; har doim IsNot Nothing bilan tekshiring.
  • Integer? - Nullable(Of Integer): 0 bilan "qiymat yo'q" ni ajratadi.
  • HasValue, Value, GetValueOrDefault(x) - asosiy a'zolar.
  • If(a, b) - zaxira qiymat berishning eng qisqa yo'li.
  • Funksiyadan Nothing emas, bo'sh ro'yxat qaytaring.

Keyingi bo'limda asinxron dasturlashni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.