1

I am manually converting some code from VBA to VB.NET, and i came acrossLet Property having 2 parameters.

This is a close enough example of what I am dealing with:

Private Property Let Base(N%, ByVal vNewValue As String)
    Dim pos As Integer
    pos = InStr(vNewValue, "  ")
    If pos > 0 Then
        cond1(N) = Left(vNewValue, pos - 1)
        cond2(N) = Right(vNewValue, Len(vNewValue) - pos - 1)
    Else
        cond1(N) = vNewValue
    End If
End Property

Things I already know: Get Property from VBA would be a ReadOnly Property in VB.NET that include a Get block.

Similarly, a Set Property from VBA would be a WriteOnly Property in VB.NET that include a Set block

So how is the Let Property from VBA done in VB.NET?

I also did a lot of googling about what Let used to mean and how to replicate its behavior in VB.NET, but sadly I couldn't find exactly what I want.

  • 2
    This might help: https://stackoverflow.com/a/5042718/212869 – NickSlash Mar 05 '23 at 18:44
  • 1
    VB.NET does not allow distinguishing between Let and Set. Not a problem when you need to implement Let: Public WriteOnly Property Base(index As Integer) As String / Set(value As String) / etc... / End Set / End Property – Hans Passant Mar 05 '23 at 19:15
  • From memory the difference between Let and Set was something to do with reference vs value types – SSS Mar 05 '23 at 22:30
  • 1
    @SSS that's right, `Let` was used for primitives (by VBA this was implicit and not required, though it still showed up in the custom property definition) and `Set` was used for object types. I think in VBA it was necessary to disambiguate between trying to assign object identity vs. using the default property of the assignee. – Craig Mar 06 '23 at 14:40
  • 1
    Just to expand on what I mean, `Let Foo = Bar` with both `Foo` and `Bar` being object types would try to assign the value of the default property of `Bar` to the default property of `Foo`, whereas `Set Foo = Bar` would unreference the instance originally pointed to by `Foo` and make `Foo` refer to the same instance as `Bar` (potentially destructing the original instance if its reference count went to zero). – Craig Mar 06 '23 at 16:40
  • 1
    As far as I know, .NET VB only supports default properties for indexing but has removed them for all other purposes, so it is no longer necessary to have separate `Let` and `Set` for parsing disambiguation. – Craig Mar 06 '23 at 16:46
  • @HansPassant Just to be clear, does that mean that Let and Set are the same in VB.NET? In other words, the code I posted would be something like: Private WriteOnly Property Base(N As Integer, ByVal vNewValue As String) / Set(value) / ' Some code / End Set / End Property – Alex Schmidt Mar 06 '23 at 17:40

1 Answers1

3

In VBA-heritage VB and ignoring custom classes and property definitions, Let was used for value assignment and Set was used for reference assignment. I don't know for certain, but I would speculate that the reason for the distinction was to disambiguate in the presence of default properties. In VBA, if I write

foo = bar

If foo and bar are both object types, this line could refer to both a reference assignment (change foo to refer to the same underlying object as bar) or a value assignment (assign the value of the default property of bar to the default property of foo). Introducing Set as an alternative to the default Let allows both to be handled:

Let foo = bar
Set foo = bar

With Let we do the default property value assignment, with Set we do the reference assignment. (Let was long since made optional, so foo = bar would be equivalent to Let foo = bar.)

The customized Property Let and Property Set would follow from this language behavior, and ideally implementations would act like the native language features, although the answers on the question reference in the comments (here: https://stackoverflow.com/a/5042718) point to some interesting things that users may have done with the additional flexibility given by two different assignment keywords.

.NET VB has discontinued default properties except for indexing, so the statement foo = bar is unambiguous: if foo is a value type, then it does value assignment, and if foo is a reference type, it does reference assignment. Thus, the Set statement has gone away, but for whatever reason, they preferred to retain the assignment side of a custom property as Set instead of Let. I don't know what the thinking was; in my experience, a custom assignment is as likely to be value-based as it is reference-based, so it isn't necessarily the case that keeping Set is more in line with the equivalent VBA code.

Specifically to your question, you would replace the custom Property Let with a custom Set block inside a property, i.e.

Public Property Base(ByVal N As Integer) As String
    Get
       '...
       'Can be omitted and property can be WriteOnly if desired
    End Get
    Private Set(ByVal value As String)
        Dim pos As Integer
        pos = InStr(value, "  ")
        If pos > 0 Then
            cond1(N) = Left(value, pos - 1)
            cond2(N) = Right(value, Len(value) - pos - 1)
        Else
            cond1(N) = value
        End If
    End Set
End Property

(I think the code would work as-is, but I would probably rewrite it to use the .NET string handling functions instead of the legacy VBA functions.)

Craig
  • 2,248
  • 1
  • 19
  • 23
  • 1
    I think that explains pretty much most of what I need, and I would say I am absolutely satisfied with that. Thanks for the time and effort you put into this. – Alex Schmidt Mar 06 '23 at 19:20
  • @AlexSchmidt if Craig's answer is a good one, please accept it as the answer, so he gets the points for his contribution – SSS Apr 14 '23 at 03:48