Description
Bug Description
Bug: Property defination overload with Public and Private visibility and overridden with ReadOnly and WriteOnly access modifier is throwing BC30301, BC30366, BC32429 and BC37243
Steps to Reproduce
- Create a VB.NET module.
- Define a Public
ReadOnly
property and a PrivateWriteOnly
property with the same name. - Observe the compiler error.
Expected Behavior
The compiler should allow Public ReadOnly
and Private WriteOnly
properties with the same name, as they serve different purposes.
Actual Behavior
The compiler throws the below errors:
- Error (active) BC30301 'Public ReadOnly Property IsResponseReady As Boolean' and 'Private WriteOnly Property IsResponseReady As Object' cannot overload each other because they differ only by return types. YYYY XXX.vb 2
- Error (active) BC30366 'Public ReadOnly Property IsResponseReady As Boolean' and 'Private WriteOnly Property IsResponseReady As Object' cannot overload each other because they differ only by 'ReadOnly' or 'WriteOnly'. YYY XXX.vb 2
- Error (active) BC31429 '_isResponseReady' is ambiguous because multiple kinds of members with this name exist in module 'ModuleZ'. YYY XXX.vb 4
- Error (active) BC37243 Auto-implemented properties cannot be WriteOnly. YYY XXX.vb 8
Code Example
Below is are code snippets which is reporting errors:
Private _isResponseReady As Boolean = False ' -Should be initially False to avoid Command/Response dialog Error
Public ReadOnly Property IsResponseReady As Boolean
Get
Return _isResponseReady
End Get
End Property
Private WriteOnly Property IsResponseReady '//Bug: VB.NET does Not allow such overloaded functions
Set(value As Boolean)
_isResponseReady = value
End Set
End Property
Current Remedy
Define Private methods 'Set+property name' to set the value of the property.
Code Example With Remedy
The remedy I adopted is as below. A slightly bigger block of code is included to show the context of the usage.
'// Define events for synchronization
Public Event CommandIssued()
Public Event ResponseRead()
Private _isResponseReady As Boolean = False '' Should be initially False to avoid Command/Response dialog Error
Public ReadOnly Property IsResponseReady As Boolean
Get
Return _isResponseReady
End Get
End Property
'Private WriteOnly Property IsResponseReady //Bug: VB.NET does Not allow such overloaded functions
' Set(value As Boolean)
' _isResponseReady = value
' End Set
'End Property
Private Sub SetResponseReady() ''Current remedy for the above bug
_isResponseReady = IsCommandReady
End Sub
Public ReadOnly Property IsCommandReady As Boolean
Get
Return Not IsResponseReady
End Get
End Property
Private Sub SetCommandReady()
_isResponseReady = IsCommandReady
End Sub
Friend Sub OnCommandIssued()
Debug.Assert(IsCommandReady, "Command/Response dialog Error. CommandIssued() Event should have a preceding ResponseRead() Event in one-to-one dialog relationship")
SetResponseReady()
'' IsResponseReady = True ''_isResponseReady = True // Bug : VB.NET does Not allow such overloaded functions
' Additional logic for when a command is issued
End Sub
Friend Sub OnResponseRead()
Debug.Assert(IsResponseReady, "Command/Response dialog Error. ResponseRead() Event should have a preceding CommandIssued() Event in one-to-one dialog relationship")
SetCommandReady()
''IsCommandReady = True ''_isResponseReady = False IsResponseReady = False // Bug : VB.NET does Not allow such overloaded functions
' Additional logic for when a response is read
End Sub
Environment
- VB.NET Version: 9.0.200 Commit: 90e8b202f2
- Target Framework: .NET 4.8.1 (or higher)
- IDE: Visual Studio Community MSBuild version: 17.13.8+cbc39bea8
- Workload version: 9.0.200-manifests.b6391994
donet--info.txt
Additional Context
This issue impacts scenarios where state needs to be encapsulated with separate read and write logic.
Other Possible Scenarios:- I need to overload a Public ReadOnly Property declaration with a Private WriteOnly Property declaration in a derived 'downstream' Class implementation.
"Further details on the impact, priority, and justification for this feature can be found in the comments below."
Real Life Scenario - Hypothetical
Here is a code snippet of a hypothetical scenario which necessitates such property overloads and overrides
Module IndianGov
' Base class representing the Prime Minister's Office
Public Class PMOffice
' Public ReadOnly property for Information
Public Overridable ReadOnly Property Information As String
Get
Return "Confidential Information"
End Get
End Property
' Public WriteOnly property for Complaints
Public Overridable WriteOnly Property Complaints As String
Set(value As String)
' Default implementation for handling complaints
Console.WriteLine("Complaint received: " & value)
End Set
End Property
End Class
' Derived class representing the NSA
Public Class NSA
Inherits PMOffice
' Override Information as Private WriteOnly
Private Overrides WriteOnly Property Information As String
Set(value As String)
' Logic for handling information privately
Console.WriteLine("NSA is handling information privately.")
End Set
End Property
' Override Complaints as Public WriteOnly
Public Overrides WriteOnly Property Complaints As String
Set(value As String)
If value.Contains("Opposition") Then
' Add to Information
Console.WriteLine("Adding complaint to Information: " & value)
ElseIf value.Contains("CurrentParty") Then
' Send to PartyHQ and execute private functions
Console.WriteLine("Sending complaint to PartyHQ: " & value)
ExtortionAndHarassmentOfComplainant()
MOSSAD.Engage.GetElectronicInfo(New List(Of String) From {"Phone1", "Phone2"},
New List(Of String) From {"Address1", "Address2"},
New List(Of String) From {"BankAccount1", "BankAccount2"},
New List(Of String) From {"Employer1", "Employer2"})
End If
End Set
End Property
' Private function for extortion and harassment
Private Sub ExtortionAndHarassmentOfComplainant()
Console.WriteLine("Executing extortion and harassment of complainant.")
End Sub
End Class
' Derived class representing the Home Secretary
Public Class HomeSecretary
Inherits PMOffice
' Override Information as Private WriteOnly
Private Overrides WriteOnly Property Information As String
Set(value As String)
' Logic for handling information privately
Console.WriteLine("Home Secretary is handling information privately.")
End Set
End Property
' Override Complaints as Public WriteOnly
Public Overrides WriteOnly Property Complaints As String
Set(value As String)
If value.Contains("ED Raid on Opposition Employee") Then
' Add to Information
Console.WriteLine("Adding complaint to Information: " & value)
ElseIf value.Contains("HomeOffice") Then
' Send to PartyHQ and execute private functions
Console.WriteLine("Sending complaint to PartyHQ: " & value)
ExtortionAndHarassmentOfComplainant()
ElseIf value.Contains("Evidence") AndAlso
(value.Contains("IAS") OrElse value.Contains("IPS") OrElse value.Contains("Judges")) Then
' Execute SecureWithPrivateDocker
SecureWithPrivateDocker(New List(Of String) From {"Phone1", "Phone2"},
New List(Of String) From {"Address1", "Address2"},
New List(Of String) From {"BankAccount1", "BankAccount2"},
New List(Of String) From {"Employer1", "Employer2"},
"Assigned IPS", "Assigned IAS", "Assigned Judge")
Else
' Call the overridden Complaints property of PMOffice or NSA
MyBase.Complaints = value
End If
End Set
End Property
' Private function for extortion and harassment
Private Sub ExtortionAndHarassmentOfComplainant()
Console.WriteLine("Executing extortion and harassment of complainant.")
End Sub
' Private function for SecureWithPrivateDocker
Private Sub SecureWithPrivateDocker(phones As List(Of String), addresses As List(Of String), bankAccounts As List(Of String), employers As List(Of String), assignedPolice As String, assignedAdministrator As String, assignedJudiciary As String)
Console.WriteLine("Securing with private Docker for:")
Console.WriteLine($"Phones: {String.Join(", ", phones)}")
Console.WriteLine($"Addresses: {String.Join(", ", addresses)}")
Console.WriteLine($"BankAccounts: {String.Join(", ", bankAccounts)}")
Console.WriteLine($"Employers: {String.Join(", ", employers)}")
Console.WriteLine($"Assigned Police: {assignedPolice}")
Console.WriteLine($"Assigned Administrator: {assignedAdministrator}")
Console.WriteLine($"Assigned Judiciary: {assignedJudiciary}")
End Sub
End Class
' Mock MOSSAD class for demonstration
Public Class MOSSAD
Public Shared Class Engage
Public Shared Sub GetElectronicInfo(phones As List(Of String), addresses As List(Of String), bankAccounts As List(Of String), employers As List(Of String))
Console.WriteLine("MOSSAD is gathering electronic information.")
End Sub
End Class
End Class
End Module