The Agenda

At long last, in the last hours of the last day of the week that marks the 33rd anniversary of Classic Visual Basic, I am finally ready to share with you my comprehensive vision for the future of the VB.NET language via ModVB.

As mentioned, last year I started out with an 11-page outline including some code examples in Word, noting ideas for some 110+ investments in completely new features or modifications to existing features collected over 12 years as a VB.NET developer and 8 years at Microsoft as a VB.NET language designer combed from countless personal experiences, customer interactions, bug reports, forum questions, etc. I set out to decompress this outline into effectively a book of concrete, thought-out designs that I could share to illustrate the language-specific scope of ModVB.

If you’re a new reader, ModVB is a Visual Studio extension I’m developing which adds new functionality to the VB language and tooling. You could think of it as a modernized extended Director’s Cut of VB to empower and be enjoyed by VB enthusiasts such as myself. I’m both attempting to crowdfund and crowdsource the project so it’s urgently important that potential supporters and contributors have an idea of what all they’re supporting.

Having said all that, while the exercise of methodically and holistically working through the entire outline has absolutely paid off, my previous draft had 120+ individual blog posts (I called chapters) written in specification-ese, and it became apparent that most folks wouldn’t see the forest for the trees. “What’s in ModVB?”

Any normal human: What’s in ModVB?

Me: Start at this link and click the “Next” link 120 times. If you skim it you’ll be done in a couple months and it’ll all make perfect sense to you.

So I’ve been aggressively editing and refactoring for the last several weeks and I decided this anniversary was my hard-deadline. Instead of my design process memoirs in 120 chapters, I’ll be sharing a mere 18 section summaries illustrating the various features primarily in concise, compelling, code. Not endless prose. Code with a few sentences here or there and I’m going to trust my audience to ask questions when they need, provide criticism when they feel, and to generally trust that I’ve done my homework on this. As short as an example may be, the process to vet the design (both for worthiness and achievability) was not short. All of these investments have a scenario somewhere. A question I was asked, probably more than once; an API I used or was blocked from using; I tool I or someone else wished they had. And every feature I propose is a feature I know I can personally implement in the Roslyn compiler (not that I will be implementing all of them). Maybe that’s a fault in my designs that I limit myself to the box of my own capabilities but it’s also my bedrock.

Further, this is not a wish list. It’s not an unfiltered collection of ideas accumulated that might or might not happen. As it stands upward of 85% of the things I show here are virtual certainties at this point. These features are shovel ready for an experienced compiler dev, and speclet ready for newbies. It’s not a question of if they’ll be implemented, just when. A small number have already been prototyped and demoed before on this blog or implemented already. There will be adjustments. Learnings. Scope changes. But this is what’s coming both because I am a VB enthusiast and am personally excited to use the vision of the language I describe, but also because creatively this is the thing which is in my soul and I have no choice but to see it through. Maybe I’ll end up homeless, destitute, coding at a public library in some warmer climate on an old laptop I aggressively guard with animal-like ferocity–I hope not–but a life creatively unfulfilled is far more terrifying.

For this first post I have included a brief description of each section and for all be the last 2 a highlight. This is not necessarily the “most important” feature in that section. In fact, it probably isn’t. Instead, it’s a selection meant to intrigue you. Especially in those sections where the top-of-mind feature is one I’ve demoed or discussed already. I want you to know there’s more and for you to feel interested in clicking the link to the full section summary after it’s posted. Each section has 6+ features it covers. A few will contain (link to) dedicated discussions of particular features which are on or near the line where your feedback and scenarios are critical. I’ll update this post as each section comes online.

Finally, the caveats for a better reading experience and better feedback:

  • Neither the sections nor the features in them are presented in priority order; do not assume because you see it first that I think it’s most important (and that you need to correct me). This isn’t a status update or a work item “backlog”; I’ll create one of those on GitHub with these items but having these descriptions available now massively facilitates a future discussion on when and how to realize these features.
  • This is not a list of everything required before releasing a v1. In fact, having now seen the entire scope I don’t think it would be good to dump that much on the world at once. It’s not a release schedule; that conversation will come later. There’s no value now in trying to “cull” some features to make it more likely some other features will happen sooner or at all.
  • While I am capable of implementing all of the features, the plan is that I won’t. Other VB community members have actually already implemented some in their own private branches and I’ll bring on contributors when I’m ready to support a proper functional responsive open source repo (with your help).
  • You might think a big part of this process was reviewing features already in other .NET languages but that’s not the case. The goal of the exercise was to find the ultimate expression of idiomatic VBness and see where that leads. I haven’t been closely looking at any other languages on .NET or off (except T-SQL) but I have a vague awareness of some new features here and there from names or screenshots I’ve seen on Twitter in the last few years. Even if a feature shares the same name as a capability in another language though the design is pure VB and hasn’t been influenced by how that capability was realized anywhere else. That said, for interop reasons alone there must be a period of reconciliation at some point in the future. This is expected, just not before the full VB-sourced vision is published.
  • I know the published VSIX and packages are woefully out-of-date. This is shameful to me. I published those manually (hand editing manifests) and my next step is to set up a proper CI/CD pipeline so that I can release effortlessly. If you’re an expert in that, please reach out!
  • If Patreon doesn’t work for you, I’m also considering other means: GitHub sponsors, Open Collective, etc. Open to suggestions. If you can’t give what you ideally would want to just give what you can. A once-annual $24 donation now is better than a $100/month donation never. If you can’t give there or now just leave a comment with your email or something, join the VB Discord, so I can keep you informed if new opportunities open up.
  • I need more scenarios for the designs I’ve created; if a scenario isn’t important to you personally, that’s ok, but don’t trash it to deprioritize. There’s someone for whom that scenario matters.
  • This is just the language/compiler/runtime stuff. There will be future (smaller) posts about IDE, tooling, and community. Look forward to it!
  • These are not “asks” or wishes. Please don’t go to Microsoft asking for individual items piecemeal. I’m not seeking permission, and we’re way past asking for permission.
  • Share and discuss everywhere!

And with that, here are the 18 sections. Right now these just include a teaser highlight but over the coming days and weeks I’ll post full section summaries separately covering all the functionality and then update this document with a link to the section summary after the highlight/short description.

The 18 Sections

Oh, just a heads-up. Because ModVB changes some semantics it might be confusing to developers whether a piece of code is using ModVB semantics or vanilla VB semantics. To make it more readily apparent the convention I’m recommending to distinguish them has two parts:

First, ModVB local variable declarations are introduced with the Let keyword (a callback to earlier BASICs). Functionally it’s identical except in a particular case I’ll cover later but mostly it’s just a visual indicator. All but the most trivial programs will include some local variables so making this stylistic change there makes it very likely that the semantics of the code will be clear.

Secondly, I’m trying out using lowercase keywords by default in ModVB. It’s still case-insensitive and I’ve actually modified the CSS on this page to only appear lowercase. When syntax colorization isn’t available I’ll likely still use PascalCase and/or bolding to emphasize keywords because I think it’s a little easier to read. I’d really love to hear feedback from readers about both of these conventions and how you feel about them. Thanks!

Finally, don’t let semantic changes confuse you, ModVB is 100% fully back-compatible with vanilla “in the box” VB provided by Microsoft, including all current and future updates. A project can choose to default to vanilla semantics and opt-in to modern semantics on a per-file basis, or vice versa. And tools to highlight and assist any transitions will be provided. It’s critically important that all existing vanilla VB code continue to work as is even while we push the frontiers or productivity.

Type-Inference Enhancements

ModVB will feature several enhancements to type inference to make it a lot smarter so you can get more benefits from static typing with fewer keystrokes.

Highlight: Control flow-sensitive local variable typing

Let control As Control = SomeFunction()

' Variable types narrow when tested or assigned.
If TypeOf control Is CheckBox Then
    control.Checked = True
End If

' Intersection (And) Types are possible.
If TypeOf control Is IButtonControl Then
    ' TypeOf control Is {Control And IButtonControl}.
    ' Members of both are available.
    control.Text = "Search"
    control.PerformClick()
End If

' Union (Or) Types are possible.
If enableFormatting Then
    control = New RichTextBox
Else
    control = New TextBox
End If

' TypeOf control Is {Control, TextBoxBase, {TextBox Or RichTextBox}}.
control.MaxLength = 200

Read the full section summary

Streamlining and Boilerplate Reduction

ModVB will include many new and improved features to make you more productive with fewer keystrokes across almost every category, but this section covers those that don’t align with other themes.

Highlight: Developers can mark fields and properties with the Key modifier. This informs the compiler to generate the default constructor with matching parameters and (optionally) implementations of GetHashCode and Equals

Read the full section summary

' Sub New(id As Guid, accountNumber As String) is generated by default.
' camelCased (configurable) parameter names are inferred.
Class AccountInfo

    Key ReadOnly Property Id As Guid

    Key ReadOnly Property AccountNumber As String

End Class

Let info = New AccountInfo(Guid.NewGuid(), "12345")

General Modernization and Evolution I

Almost every basic kind of statement in VB is being revisited with some tweaks, including historically the most requested features from VB users!

Highlight: The Select Case statement will be enhanced with many new tests including identity, types, shapes, and more

' Identity
Select Case sender
    Case Is Button1
        
    Case Is Button2
        
    Case Is Null
        
End Select

' Type (works with control flow-sensitive typing)
Select Case TypeOf obj
    Case String
        
    Case Integer
        
End Select

' Shape (pattern matching)
Select Case ShapeOf int
    Case b As SByte
        
    Case s As Short
        
    Case Else
        
End Select

Full section summary coming soon!

UI, XML, and XAML

It’s no secret by now that ModVB is upgrading XML literals to full XAML literals to enable more productive uses such as web and cross-platform mobile development. I’ve published several videos of earlier prototypes of this work already so for this section I’ll highlight something you haven’t seen already.

Highlight: XML/XAML literals will allow embedded block expressions allowing for the use of all statements when generating nested content

<html>
  <body>
    <{
      For Each customer In customers
          If TypeOf customer Is PreferredCustomer
              <div>
                <h1><{customer.Name}></h1>
                <p><{customer.PreferredStatus}></p>
                <p><{customer.EmailAddress}></p>
              </div>
          Else
              <div>
                <h2><{customer.Name}></h2>
                <p><{customer.EmailAddress}></p>
              </div>
          End If
      Next
    }>
  </body>
</html>

Full section summary coming soon!

JSON and JSON Pattern Matching

ModVB already supports JSON literal expressions and JSON pattern matching so I’ll highlight new functionality planned for these features.

Highlight: JSON literals will be enhanced to not only create JSON types like JsonObject and JObject but to initialize arbitrary .NET types. This will smooth transitions during development from weakly-typed APIs to strongly-typed APIs but also will accelerate automated test authoring in combination with JSON-producing technologies such as SQL Server and Postman

Let testContacts As InMemoryRepository(Of Contact) =
    [
      {
        "name": "Tyrion",
        "email": "gotaw@lannister.wes"
      },
      {
        "name": "Jon",
        "email": "bastard@stark.wes"
      },
      {
        "name": "Dany",
        "email": "khaleesi@targ.ess"
      }
    ]

Full section summary coming soon!

Strings and String Pattern Matching

Strings are everywhere! Several enhancements are planned for working with them more productively.

Highlight: Pattern Matching will be enhanced to support an interpolated string syntax for matching and inspecting strings; these can be used anywhere patterns can be specified, including within other patterns

Select Case ShapeOf username
    Case $"{user}​@{domain}​"
        ' External email
        If domain = "mydomain.com" Then
            Throw New Exception("Please use domain account.")
        End If
        
    Case $"MYDOMAIN\{user}​"
        ' Internal domain
        
    Case $"{domain}​\{user}​"
        ' Affiliated domain
        
End Select

Full section summary coming soon!

Generalized Pattern Matching

Beyond JSON and XML, ModVB will support generalized pattern matching for arbitrary .NET objects.

Highlight: Developers will be able to define, compose, and use their own custom named pattern methods

If ShapeOf coordinate Is Polar(r, theta) Then
    
ElseIf ShapeOf coordinate Is Cartesian(x, y) Then
    
End If


If ShapeOf str IsNot ip As IPAddress Then Return

Full section summary coming soon!

General Modernization and Evolution II

Basic statements aren’t the only language elements being revisited in ModVB. Declarations and expressions are also getting overdue updates based on common usages and longstanding community requests.

Highlight: ModVB will add a pipeline operator (->) to VB, letting you call any method like an extension method (postfix syntax) and to make nested function calls, such as in data transformations, read in execution order (left-to-right, top-to-bottom) instead of inside-out

' Before
Dim last6 = Right(str, 6)

Dim result = ComputeResult(obj)

Dim emails = GenerateEmails(ComputeInvoices(GetMonthlyOrders(calendar), priceList), addressBook)

' After
Let last6 = str -> Right(6)

Let result = obj -> ComputeResult()

Let emails = GetMonthlyOrders(calendar) ->
             ComputeInvoices(priceList) ->
             GenerateEmails(addressBook)

Full section summary coming soon!

LINQ Enhancements

LINQ was introduced to VB 16 years ago. ModVB will add new query operators as well as integrate queries with other constructs. I’ve previously shown a prototype of integration of queries with For Each so I’ll highlight another example here.

Highlight: Object member and collection initializer enhancements

' Initialize any collection with a query.
Let dayNames =
      New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
            From
              day In DayOfWeek.Sunday To DayOfWeek.Saturday
            Select
              day.ToString()

' Nest member and collection initializers.                               
Let order = New Order(orderId) With {
                  .OrderNumber = orderNumber,
                  .Options With {
                     .ExpeditedShipping = True,
                     .GiftWrapping = True
                   },
                  .Items From item In items Where item.Quantity > 0
                }

Full section summary coming soon!

Late-Binding/Dynamic Programming Enhancements

Late-Binding has been a part of VB since the beginning. Whether interoperating with Office or other COM APIs, or emulating the untyped or gradually typed systems of dynamic languages for rapid development, late-binding has its place in modern development. To that end, ModVB will include several investments to make late-binding more powerful than before so that VB programs can achieve maximum productivity wherever they fall on the static-dynamic spectrum.

Highlight: ModVB will change the late-bound type from Object

Let lbo As LateBound = New ExpandoObject

lbo.Number = 10
lbo.Increment = Sub() lbo.Number += 1

' Before calling Increment.
Console.WriteLine(lbo.Number)

lbo.Increment()

' After calling Increment.
Console.WriteLine(lbo.Number)

' Implicit type of (non-local) declarations is LateBound
' rather than Object, for typeless programming a la
' Python/Ruby/JavaScript.
Class Person
    Key Name, Age

    Sub Say(Optional message)
        If message Is Null Then
            Console.WriteLine("Hello! My name is " & Name)
        Else
            Console.WriteLine(message)
        End If
    End Sub
    
    Function GetFutureAge(yearsFromNow)
        Return Age + yearsFromNow
    End Function
End Class

Full section summary coming soon!

Async Enhancements

It’s been 12 years since Async methods and Await expressions were added to VB. It’s time to take what we’ve learned to make asynchronous programming even more productive and more deeply integrated into the language.

Highlight: In ModVB the result of an asynchronous method invocation can be “dotted” into (among other things) immediately; the asynchrony will propagate to the resulting value

' Before
Dim service = New RemoteStorageService

' Nobody wants to write it like this:
Dim blob = Await (Await (Await service.GetFileAsync("filepath")).OpenAsync()).ReadAllBytesAndCloseAsync()

' So, we write it like this:
Dim fileHandle = Await service.GetFileAsync("filepath")
Dim stream = Await fileHandle.OpenAsync()
Dim blob = Await stream.ReadAllBytesAndCloseAsync()

' After
Let service = New RemoteStorageService

' Write it as fluently as synchronous code.
Let blob = Await service.GetFileAsync("filepath") _
                        .OpenAsync() _
                        .ReadAllBytesAndCloseAsync()

Full section summary coming soon!

Null and Nothing

Nulls are real and inescapable. ModVB will treat them such but with deep language integration that makes working around them safer and more productive than ever!

Highlight: Expressions that use the new ? operator or various null-safe operators (e.g. ?.) will propagate null-safety to certain operators and statements that use them

' Before
' If obj is null, this will attempt to await a null task, and throw.
Dim collection = Await obj?.GetCollectionAsync()

' Is it this?
Dim collection = Await If(obj Is Nothing,
                          Task.FromResult(Nothing),
                          obj.GetCollectionAsync(cancellationToken)
                       ).ConfigureAwait(False)

' No, it's probably this.
Dim collection = If(obj Is Nothing,
                    Nothing,
                    Await obj.GetCollectionAsync(cancellationToken) _
                             .ConfigureAwait(False)
                 )

If collection IsNot Nothing Then
    For Each item In collection
        
    Next
End If

' After
Let collection = Await obj?.GetCollectionAsync()

For Each item In collection?
    
Next

Full section summary coming soon!

Declarative Programming and Code Generation

VB has a strong historical tendency toward declarative styles of programming. With the advent of source generators even more opportunities are on the horizon for developers to say what they want while delegating the details of how to the system. ModVB will include several investments to support a breadth of declarative scenarios both with and without source generators.

Highlight: Special “Smart Attributes” will enable auto-property and auto-event implementations to reuse common patterns without the use of source generators

Class ListingInfo
    Implements INotifyPropertyChanged
    Implements IDataErrorInfo

    ' Smart-Attributes can be combined to transform and react to values one
    ' after another.
    <Trim, Notify, Undoable, MaxLength(25)>
    Property Title As String = "New Listing"

    ' Compiler has no knowledge of specific Smart-Attributes, only patterns
    ' of integration at well-defined points such as 'on entry',
    ' 'before set', 'after set', 'on leave', etc.
    <ThrowOnNull, Notify, Undoable, MaxLength(50)>
    Property Description As String = "No description."

    ' Smart-Attributes can take dependencies on members of types in which 
    ' they are applied.
    <ForceToUtc, Notify>
    Property LastSaved As Date

    <Notify, Undoable,
     Regex("^\d{3}-\d{2}-\d{4}$", "Must be of the form '###-##-####'.")>
    Property ListingCode As String = "<None>"

    ' Simple implementation of INotifyPropertyChanged and IDataErrorInfo
    ' omitted for space.
    ' Could be user-declared, generator-declared, or in a base class.
End Class

Full section summary coming soon!

New Types and New Kinds of Types

This section mostly entails discussions of potentially integrating new types (e.g. Half and Int128), new type syntax, and new kinds of types (e.g. Or types) into the VB language.

Highlight: Could a library of units of measure be implemented in Vanilla VB? What would that look like? What are the minimal and ideal changes that could be made to the language to provide the best experience? Is it even worth it?

Let G = 9.8(In m/s^2)
Let speed = G * 5(In s)

Full section summary coming soon!

Inheritance, Interface Implementation, and Extension

Object-based programming techniques such as implementation inheritance are powerful but sometimes a little too rigid. What can we add to VB to make OOP less tedious?

Highlight: ModVB will allow types to delegate some or all of an interface’s or base type’s overridable members to contained fields (or properties)

' Composition over inheritance made easier by delegating interface
' implementation partially or wholly to contained objects.
Private ErrorHelper As New DataErrorInfoHelper Implements IDataErrorInfo

Full section summary coming soon!

Performance and Interoperability

The .NET platform is always evolving and it’s important to VB enthusiasts that we can continue to leverage new APIs (e.g. Span(Of T)) and write code that benefits from the latest platform performance improvements. ModVB will approach each scenario at the right level of abstraction while leaving escape hatches for edge cases.

Highlight: The ModVB compiler will recognize calls to certain well-known methods and emit these calls as CLR native instructions. This will give VB users access to the full expressivity of the .NET runtime even when a language-specific syntax for such instructions is not available

' Because IL literals would be too much.
Imports VB.Runtime.NativeInstructions.IL

' Emits IL similar to the following code in C#:
'
' int* ptr = stackalloc int[32];
Let ptr As IntPtr = 
      sizeof(Of Integer)() ->
      conv_u() ->
      mul(32U) ->
      localloc()

Full section summary coming soon!

Runtime Library Enhancements

The VB runtime library is more than a collection of useful functions, it’s required for virtually any VB program to execute using the language’s semantics. From late-binding to simple intrinsic conversions this library must be kept up to date, both with the evolving language and its uses. Several investments will be made to optimize the performance of the runtime, fix bugs, and add new and improved functionality.

Full section summary coming soon!

Deprecations

As stated in my introduction, ModVB will be 100% back-compatible with vanilla VB insofar as projects may configure whether to use modern or vanilla semantics by default, and source files may further opt into (or out of) modern semantics individually. Combined with the partial types feature, code can migrate to ModVB semantics with method-level granularity.

That said, within the modern semantics there are obviously changes—cases where the exact same syntax behaves differently under modern semantics. I’ve tried to be very intentional with these changes and to keep them few and either high value new functionality such as improved type inference, or to places where the entire language can be made more self-consistent for current and future users. However, beyond these cases, it’s worth discussing a very small number of language constructs or semantics that exist in vanilla VB but which might not be supported moving forward under modern semantics. This section contains a summary of proposed deprecations for discussion.

Full section summary coming soon!

What’s Next?

Next, I upload the remaining 19 parts of this publication (18 section summaries + wrap up/next steps). I’m hoping to upload one full section summary every 2-3 days. It’s a process of moving content from Word to WordPress, along with manually colorizing, checking, and correcting dozens of code samples. Sometimes this may go faster or slower but I figure just for the sake of the audience it’s best to post no more frequently than once per day so that you have a change to read the entire section, noodle on it, leave some feedback, etc. I’ll be trying to keep active in the comments and on Twitter so feel free to reach out. When you’re staring down this much clerical work, it’s nice to come up from air now and then.

Please share and discuss… everywhere!

Regards,

-ADG

Special Thanks to ANYONE who is donating or has ever donated to me via Patreon! I could not pursue my dream of producing modern VB features and content without their support.

ALEX T., JONATHON M., DR. DONNA M., DR. ANNE J., KEVIN R., KIRILL O., NEAL G., GOVERT D., TAIWO A., PETER B., AND PAUL C.

7 thoughts on “The Agenda

  1. In XAML I wish to add capability to write relative binding using mathematical and complex functions.

    Simple Ex:

    1. In xaml of a textbox, I want the width property to be 10 characters * font weight (of current font)
    2. checkbox UI with tick or On/Off button as binding of a function from a module.

    Liked by 1 person

    • Wonderful examples. There’s a topic in that section that’s relevant to that. In short, I could build unidirectional and bidirectional data-binding easily-ish but it’s a question of whether it’s bloat. Very much look forward to feedback on that. Thanks for reading!

      Like

  2. Something I think that would benefit a lot of people and is low hanging fruit is Unchecked math. It works today on a project level. but it would like to see it at least as a function like Unchecked( Long.Max + 1) where anything in between the () does not throw an overflow exception. A stretch would be an unchecked region of code, all the plumbing is already there. I implemented the function version in Roslyn years ago before the “no new features” edict, but it was never reviewed.

    Liked by 1 person

    • This request is always on my mind. I haven’t forgotten it and will discuss it. The one scenario I could remember off the top of my head was hashcode calculations but I thought “Surely there are more”. I can’t not do something about it though. A little known secret is that the VB compiler itself won’t work with overflow checking on. The reason being that when you compute the value of a hex, octal, or binary literal… it requires performing an unchecked conversion. &HFFFFS is calculated like an unsigned number and then violently reinterpreted as a signed one. I suppose there could be workarounds but ideally the compiler could do it’s work with or without overflow checking enabled at the project level.

      Like

    • With that all said, *at a minimum*, the native instruction helpers design I highlight in the Performance and Interop section will expose all of both the checked and unchecked operations the runtime supports. I could also see Checked and Unchecked modules in the runtime to expose that functionality in a friendlier way. It really depends on how wide spread the scenarios are, but we’ll definitely address unchecked math one way or another.

      Like

  3. Maybe large language models can save time in writing feature specifications. I’ve tried asking an AI (called glm-4-9b-chat-1m) for the meaning of one of your example codes. The answer is nearly correct. I know that it’s an illusion of this AI. But the generated content is still useful. Here’s the chat log:

    <|user|>

    What’s the meaning of the following code?

    “`vbnet

    class AccountInfo

    key readonly property Id as Guid

    key readonly property AccountNumber as string

    end class

    “`

    <|assistant|>

    The provided VB.NET code snippet defines a class named AccountInfo with two read-only properties. Here’s a breakdown of what each part means:

    • class AccountInfo: This line starts the definition of a class named AccountInfo. In VB.NET, classes are used to define objects, which are instances of the class. In this case, AccountInfo is likely meant to represent some kind of account information.
    • key readonly property Id as Guid: This line defines a property named Id within the AccountInfo class. The key keyword is used to indicate that this property is a primary key, which typically means it is a unique identifier for each instance of the class. The readonly keyword specifies that the property can only be read and cannot be changed after it is assigned a value. The property keyword indicates that this is a property, not a method. The Id property is of type Guid, which stands for Globally Unique Identifier, a 128-bit number used to uniquely identify items.
    • key readonly property AccountNumber as string: This line defines another property named AccountNumber within the AccountInfo class. Similar to the Id property, this property is marked as a primary key and is read-only. The AccountNumber property is of type string, which means it can hold a sequence of characters, such as a string that represents a unique account number.

    In summary, the AccountInfo class has two primary key properties: Id and AccountNumber. These properties are read-only, meaning they cannot be modified after an instance of the class is created. They are likely used to store unique identifiers for each account, which could be used for data retrieval or to ensure that each account is uniquely identifiable.

    <|user|>

    When I use the key keyword on a property, does the compiler write GetHashCode and Equals for me?

    <|assistant|>

    In VB.NET, when you use the key keyword on a property, the compiler generates the GetHashCode and Equals methods for you, provided that the property is of a type that the compiler can handle as a key. This is typically the case for value types such as Int32StringGuid, and other types that have a well-defined hash code and equality implementation.

    Liked by 1 person

Leave a reply to Anthony D. Green Cancel reply