dotnet / dotnet/vblang

Support object initialiser syntax in any expression (not just constructor calls).

Open
#336 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
328
Forks
71
PR merge metrics
No merged PRs in 30d

Description

First the code:

```vb
Public Module Module1
Private Class CPerson
Public ReadOnly Name As String
Public ReadOnly Age As Integer

Public SomethingElse As String

Public Sub New(ArgName As String, ArgAge As Integer)
Me.Name = ArgName
Me.Age = ArgAge
End Sub
End Class

Public Sub Main()
'you can use object initialisers when constructing objects via New.
Dim p1 = New CPerson("John Doe", 50) With {.SomethingElse = "works"}

'but you can't do the same when constructing via a (factory) method.
Dim p2 = MakePerson() With { .SomethingElse = "doesn't work" }
End Sub

Private Function MakePerson() As CPerson
Return New CPerson("John Doe", 50)
End Function
End Module
```

As shown above on `Dim p1 = ...` you can use the very handy [object initialiser](https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/objects-and-classes/object-initializers-named-and-anonymous-types) syntax to set fields after an object is created and do so using a compact syntax, with the whole thing being treated as an expression, making it possible to write code like:

```vb
Return New CPerson("John Doe", 50) With {.SomethingElse = "works"}
```

Sadly, this syntax does not work if the object is created using a factory method:

![vs_factory_with](https://user-images.githubusercontent.com/20465797/44682852-3a2c8500-aa4d-11e8-8ec5-33a80835fc24.png)

Constructing objects indirectly via functions is common enough that I believe this "syntactic sugar" enhacement of an existing feature would add significant value.

In general, we would be saying that expressions of the form `Expr With { .Foo = "Blah" }` are converted to the following:

```vb
Dim temp = Expr
With temp
.Foo = "Blah"
End With
'return/pass temp to where it was expected.
```

Since `Expr` can be anything, this would allow object initialiser syntax to be used with `New ...` expressions, (factory) method calls like `MakePerson()` and even regular variables:

```vb
Dim p = New CPerson(...)
'do other stuff here
Return p With { . SomethingElse = "this works too" }
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.