Nullable Вложенные объекты и Монада Может быть - PullRequest
1 голос
/ 19 сентября 2011

Я изо всех сил пытаюсь реализовать возможно монаду - которую я назвал Nullable в этом примере.

Класс Nullable реализован следующим образом:

Public NotInheritable Class Nullable(Of TClass)

    Private _value As TClass
    Private _hasValue As Boolean

    Public Shared Function Create(ByVal value As TClass) As Nullable(Of TClass)
        Return New Nullable(Of TClass)(value)
    End Function
    Public Shared Function Create() As Nullable(Of TClass)
        Return New Nullable(Of TClass)()
    End Function

    Private Sub New()
        HasValue = False
    End Sub
    Private Sub New(theValue As TClass)
        Value = theValue
        HasValue = True
    End Sub

    Public Property Value() As TClass
        Get
            Return _value
        End Get
        Private Set(value As TClass)
            _value = value
        End Set
    End Property

    Public Property HasValue() As Boolean
        Get
            Return _hasValue
        End Get
        Private Set(value As Boolean)
            _hasValue = value
        End Set
    End Property

End Class

Существует родительский класс, реализованный как

Class Parent
    Public Property ChildClass as Nullable(Of Child)
End Class

и детский класс просто

Class Child
    Public Property ID as String
    ... other properties below ...
End Class

Способ реализации монады в данный момент. Мне нужно выполнить следующее для доступа к свойству вложенного дочернего класса

dim id = MyParentClass.ChildClass.Value.ID

но в идеале я хотел бы иметь следующее утверждение:

dim id = MyParentClass.ChildClass.Id

и если ChildClass имеет значение null, просто верните значение по умолчанию для типа свойства.

Я попытался реализовать это с помощью свойств по умолчанию и установить значение по умолчанию через атрибут, но он не скомпилировался.

Это будет возможно, или, может быть, есть лучший способ его создания - или, может быть, я просто не "получил", может быть, монаду?

Многие TIA

Simon

1 Ответ

2 голосов
/ 19 сентября 2011

Ну, само определение Maybe - это просто одно значение, которое может присутствовать или не присутствовать, так что многое вполне подойдет.Кстати, если вам не нравится название «Возможно» по какой-то причине, я бы предложил рассмотреть «Option» вместо «Nullable», поскольку Nullable уже используется .NET (для той же цели, даже--но только с типами значений), в то время как Option - это то, что F # называет это, и согласованность хорошая.

В любом случае, с этим значением можно сделать две вещи - применить преобразование к значению (если он есть), и свернуть вложенные слои (например, превратив обнуляемый из noolable из «foo» в просто обнуляемый из «foo»).Вы можете делать все остальное, учитывая эти и возможность создавать новые значения.

Операция "transform" наиболее просто реализуется с помощью лямбды (сравните метод Select, используемый LINQ - это то же самое), либо применяя его к упакованному значению, либо отбрасывая его, если значение отсутствует.Операция «коллапса» довольно проста;просто сохраняйте внутреннюю ценность, если она существует.LINQ - это очень естественный подход: вы можете думать о Maybe как о представляемой перечисляемой последовательности не более чем из одного элемента.,Плохая новость заключается в том, что я не думаю, что есть какой-то другой способ.

Я подозреваю, что вы действительно хотите здесь, чтобы неявно применить операцию "transform" с использованием обычного синтаксиса вызова метода, тогда какавтоматическое применение операции «сворачивание», если метод также возвращает что-либо обнуляемое, и, возможно, предоставление значения по умолчанию при попытке непосредственного использования пропущенного значения.Это разумный дизайн и очень удобный для использования, но я не думаю, что это возможно здесь (я сам попробовал несколько вариантов, используя C #, и я не думаю, что VB.NET отличается достаточно, чтобы помочь).Конечным результатом такой схемы является возможность вызывать методы с нулевыми значениями и возвращать нулевое значение вместо исключения нулевой ссылки.В качестве иллюстрации, вот что-то похожее в Ruby , реализованное с небольшим количеством хитростей метапрограммирования, которые я не думаю, что VB.NET может поддерживать.Я смутно припоминаю, как видел подобные идеи в Javascript и некоторых других языках.

Короче говоря, я думаю, что у вас в основном правильная идея, но то, что вы пытаетесь реализовать, к сожалению, невозможно.

...