Coding a Default Property

106 31
The concept of a "default property" for an object isn't what it used to be. Programmers new to VB.NET after 2001 (When VB6 was taken behind the barn and shot.) may not even be aware of how it used to be. In brief, you used to be able to write code like this:

TextBox1 = "Text"
This was really shorthand for ...

TextBox1.Text = "Text"
... because the Text property was the default property.

VB.NET continues to include a "Default" property attribute, but it's not at all the same.


In fact, the way it's really used is documented in such an obscure way at Microsoft that there is a real need for some clarification.

The Microsoft documentation for declaring a Default Property in a Class definition is fairly straightforward. But you have to read the whole thing. The initial step-by-step instructions don't work. You could get the idea that all you have to do is simply use the Default keyword instead of Private, Public, or Shared.

Default Property myProperty(ByVal index As Integer) As String
There are a few more rules.
  1. The new VB 2010 "auto implemented" property syntax doesn't work. In other words, you also need a Get and Set and an End Property. (But, Microsoft doesn't make this part of their documentation.)
  2. You have to use at least one parameter for the property. (There's more to this rule, too.)

You might think that you can just write this code:

' Code in a calling procedureDim theInstance As New aClassExampleMsgBox(theInstance)Public Class aClassExamplePrivate m_myProperty As String = "Red"Default Property myProperty(ByVal theDefaultArg As Integer) As StringGetmyProperty = m_myPropertyEnd GetSet(ByVal value As String)m_myProperty = valueEnd SetEnd PropertyEnd Class

No. An ArgumentException is thrown. It's fairly obvious to see that an argument must be passed, but the language of the exception message is curious:

In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user.
So, this isn't just a default property, it's also an indexed property. That's something that the documentation doesn't make clear. The code that does work simply adds the parameter to the instance in the calling procedure:

MsgBox(theInstance(1))
What does the "1" parameter do in this code? Absolutely nothing. But it still has to be there. In other words, there is no way to write a default property that is not indexed.

The right way to think of a "default" property in VB.NET is to substitute the word "indexed" for "default". In VB.NET, you can create a property that makes it simpler to define indexes to a collection. Microsoft just used the keyword "Default" for this type of property. Many sources, in fact, refer to a VB.NET default property as an indexer because that's what it does.

Here's an example that does it right. This code declares an indexer in the class DefaultPropClass. This indexer is capable of returning a member of an array that is maintained in an instance of the class by either an index number or a string that matches an element of the array.

Public Class DefaultPropClassPrivate m_theProperty As List(Of theStructure)Public Sub New()m_theProperty = New List(Of theStructure)End Sub' This ReadOnly Property returns the ' value corresponding to an integer indexDefault Property theProperty(ByVal index As Integer) As theStructureGetReturn m_theProperty(index)End GetSet(ByVal value As theStructure)m_theProperty.Add(value)End SetEnd Property' This ReadOnly Property returns the ' value corresponding to a string keyDefault ReadOnly Property theProperty(ByVal index As String) As theStructureGetFor Each p As theStructureIn m_thePropertyIf p.theKey = index ThenReturn pEnd IfNextReturn NothingEnd GetEnd PropertyEnd ClassPublic Structure theStructureDim theKey As StringDim theValue As StringEnd Structure
The code that uses this class might look like this:

Dim aCollection As New theStructureaCollection.theKey = "1"aCollection.theValue = "George"Dim aInstance As New DefaultPropClassaInstance(1) = aCollectionaCollection.theKey = "2"aCollection.theValue = "Jeremy"aInstance(2) = aCollectionMsgBox("Integer parameter 1: " &aInstance(1).theValue)MsgBox("String parameter 1: " &aInstance("1").theValue)
The value returned by the integer parameter 1 is "Jeremy" since the collection is zero based. the value returned by the string parameter "1" is "George". You might be asking, "Where is anything defaulted?" One way to answer the question is to note that this code also works:

MsgBox("String parameter 1: " & aInstance.theProperty("1").theValue)
In other words, by using a default property you can avoid typing the text ".theProperty" in your code. It doesn't seem worth it. This might help explain why Microsoft has made upgrading their documentation on this a (a-hem) secondary priority. In fact, at the very end of one Microsoft page, they're pretty blunt about it:

You should consider not defining default properties. For code readability, you should also consider always referring to all properties explicitly, even default properties.
Source...
Subscribe to our newsletter
Sign up here to get the latest news, updates and special offers delivered directly to your inbox.
You can unsubscribe at any time

Leave A Reply

Your email address will not be published.