سؤال

أواجه بعض الصداع باستخدام الهياكل والوظائف التي لا تعيد شيئًا في vb.net.

اسمحوا لي أن أحاول أن أشرح هنا مع هذا الرمز:

Public Class Form1
    Structure Test
        Dim field1 As String
    End Structure

    Private Function Foo() As Test
        Return Nothing
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim st As Test = Foo()
    End Sub
End Class

في الكود السابق ، عندما لا أعيد أي شيء نتيجة لوظيفة FOO ، أتوقع ذلك شارع هو لا شئ. لكن هذا ليس ما يحدث.

ثم وجدت في وثائق MSDN:

تعيين أي شيء لمتغير يضبطه على القيمة الافتراضية لنوعه المعلن. إذا كان هذا النوع يحتوي على أعضاء متغيرون ، فسيتم تعيينهم جميعًا على قيمهم الافتراضية.

لذلك اكتشفت ذلك عندما أخصص لا شئ إلى هيكل ، يتم تعيين جميع أعضائه على قيمهم الافتراضية ، بدلاً من البنية نفسها.

أيضا ، حاولت أن أجعل شارع نوع لاغية عن طريق الإعلان:

    Dim st As Nullable(Of Test) = Foo()  

لكن ، ما زلت لا أستطيع التحقق إذا شارع لا شيء باستخدام:

    If st Is Nothing Then  

أو

    If st.Equals(Nothing) Then

لذلك ، الأسئلة:
1 - هل من الممكن تعيين لا شئ إلى الهيكل وليس لأعضائها؟
2 - كيف يمكنني التحقق مما إذا كانت قيمة بنية الإرجاع لا شئ?

هل كانت مفيدة؟

المحلول

الهيكل هو نوع القيمة ، لا يمكن أن يكون لا شيء. يمكن للنوع الباطل أن يحل مشكلتك ، ووضع علامة استفهام بعد اسم النوع لجعله قصيرًا وسعدًا. هذا مثال:

Module Module1

    Structure Test
        Dim field1 As String
    End Structure

    Private Function Foo() As Test?
        Return Nothing
    End Function

    Sub Main()
        Dim st As Test? = Foo()
        Debug.Assert(st is Nothing)
    End Sub

End Module

نصائح أخرى

يتم استخدام أول طريقتين التاليتين بشكل متكرر في إطار .NET. تعتمد الطريقة التي تستخدمها على متطلباتك. سأستخدم الطريقة رقم 3 إذا تم اختبار الهيكل بشكل غير متكرر. للاختبار المتكرر ، سأستخدم الطريقة رقم 1 إذا كانت الطريقة رقم 2 غير مناسبة للاختبار "الفارغ". على سبيل المثال ، Point يحدد الهيكل نقطة فارغة على أنها {x = 0 ، y = 0} ، والتي لا أعتقد أنها صحيحة. لذلك ، أود استخدام الطريقة الأولى في تنفيذ بنية النقطة الخاصة بي.

الطريقة 1: تحديد Empty اختبار لاختبار المقارنة

أضف مشترك Test لاستخدامها في الفرق الفارغة.

Structure Test
    Public Shared Empty As Test = New Test
    Dim field1 As String 
End Structure 

اختبار على النحو التالي:

If st = Test.Empty Then

الطريقة 2: تحديد IsEmpty خاصية للاختبار

تحديد IsEmpty الممتلكات القائمة على الحالة الداخلية للهيكل.

Structure Test 
    Public ReadOnly Property IsEmpty As Boolean
        Get
            Return Len(field1) = 0
        End Get
    End Property
    Dim field1 As String 
End Structure 

اختبار على النحو التالي:

If st.IsEmpty Then

الطريقة 3: استخدام Nullable (من T)

تعريف على النحو التالي:

Dim st As Test? = Foo() 
'--or--
Dim st As Nullable(Of Test) = Foo()

اختبار على النحو التالي:

If st Is Nothing Then
'--or--
If st.HasValue = False Then

ملحوظة

لم أختبر الرمز أعلاه وليس لدي إمكانية الوصول إلى مكتبة الكود الخاصة بي.

إلهام

ألق نظرة على Microsoft's Point و Color الهياكل ، باستخدام التعليمات البرمجية المصدر المنشورة أو استخدامها .NET Reflector.

لا يوجد مفهوم مثل تعيين "لا شيء للهيكل وليس لأعضائه".

يبدو أنه يجب أن تنظر إليه كثيرًا أنواع القيمة الباطلة و Nullable(Of T) - إذا كنت بحاجة إلى أن تكون قادرًا على تمثيل عدم وجود قيمة "حقيقية" لنوع القيمة ، فهذا هو على وجه التحديد سبب اختراعها.

انصح Byte فمثلا. أ Byte يمكن أن يكون للقيمة أي من 256 قيم (0-255). إذا قمت بتعيينها القيمة Nothing, ، هذا سيجعله في الواقع 0. لا يمكن أن يجعلها "بعض القيمة ليست في النطاق 0-255" لأنه سيتم تخزينه كايت. أنا أعتبره مؤسفًا إلى حد ما أن VB يفعل دعك تستخدم Nothing هنا ، في الواقع ... لأن قيمة "مفقودة" من الناحية الفلسفية والقيمة 0 هي أشياء مختلفة جدًا بالفعل.

على أي حال ، تلتزم أنواع القيمة الباطلة أنواع القيمة "العادية" وتوفير قيمة منطقية إضافية لتقول ما إذا كان هناك حقًا قيمة مفيدة أم لا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top