VB.NET Структуры и Ничто - проблемы - PullRequest
6 голосов
/ 03 июля 2010

У меня есть некоторые головные боли при использовании структур и функций, которые ничего не возвращают в 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

Впредыдущий код, когда я возвращаю Nothing в результате функции Foo, я ожидаю, что st равно Nothing .Но это не то, что происходит.

Тогда я обнаружил в документации MSDN:

Присвоение переменной переменной Nothing устанавливает для нее значение по умолчанию для объявленного типа.Если этот тип содержит переменные элементы, все они имеют свои значения по умолчанию.

Итак, я обнаружил, что когда я присваиваю Nothing структуре, все ее элементы устанавливаются на ихзначения по умолчанию вместо самой структуры.

Также я попытался сделать st типом Nullable, объявив:

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

, ноТем не менее, я не могу проверить, является ли st Ничем, используя:

    If st Is Nothing Then  

или

    If st.Equals(Nothing) Then

Итак, вопросы:
1 - Можно ли присвоить Nothing структуре, а не ее элементам?
2 - Как проверить, имеет ли возвращаемое значение структуры Nothing ?

Ответы [ 3 ]

17 голосов
/ 03 июля 2010

Структура является типом значения, это не может быть Nothing.Тип Nullable может решить вашу проблему, поставьте знак вопроса после имени типа, чтобы сделать его коротким и быстрым.Вот пример:

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
11 голосов
/ 03 июля 2010

Первые два следующих метода часто используются в .NET Framework.Метод, который вы используете, будет зависеть от ваших требований.Я буду использовать метод № 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 (Of 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 Point и Color, используя опубликованный исходный код или .NET Reflector .

0 голосов
/ 03 июля 2010

Нет такого понятия, как присвоение «Ничего структуре и не ее элементам».

Звучит очень похоже на типы значений Nullable и Nullable(Of T) - если вам нужно представить отсутствие "реального" значения для типа значения, это точно причина, по которой оно было изобретено.

Рассмотрим Byte например.Значение Byte может иметь любое из 256 значений (0-255).Если вы присвоите ему значение Nothing, это фактически сделает его 0. Он не может сделать это «каким-то значением, не входящим в диапазон 0-255», так как оно будет сохранено как байт .Я считаю несколько прискорбным, что VB позволяет позволять вам использовать Nothing здесь, на самом деле ... потому что с философской точки зрения "пропущенное" значение и значение 0 действительно очень разные вещи.

В любом случае, типы значений, допускающие значение NULL, оборачивают «нормальные» типы значений и предоставляют дополнительное логическое значение, чтобы указать, действительно ли действительно является полезным значением или нет.

...