MustOverride Properties with mixed access level Get / Set - vb.net

Visual Basic allows for properties with mixed access levels, for example
Public Property Name() as String
Get
End Get
Friend Set(ByVal value As String)
End Set
End Property
Is there a way to define a MustOverride property with mixed getter/setter access level?

Hmm... you can in C# very easily:
public abstract string Foo { get; protected set; }
Unfortunately Reflector creates invalid VB when I decompile that...
EDIT: Having looked at a few bits of documentation, I suspect you can't do this :( The MustOverride documentation states:
Incomplete Declaration. When you
specify MustOverride, you do not
supply any additional lines of code
for the property or procedure, not
even the End Function, End Property,
or End Sub statement.
That suggests to me that you can't specify the different access levels :(

Related

Make static member persistent

I have one class with a private static (shared, since I'm in VB.BET) field and its associated public static property, since it stores one variable that should be the same to all the instances of this class.
My Class looks like this:
Public MustInherit Class NitrogenController
Private _active As Boolean
Private Shared _controlInterval As TimeSpan
Private _lastControlTime As Date
Public Property Active() As Boolean
Public Shared Property ControlInterval() As System.TimeSpan
'other properies that must be persisted
Public Function Control() As Boolean
If Not Now > _lastControlTime.Add(_controlInterval) Or Not _active Then
Return False
Else
DoControl()
_lastControlTime = Now
Return True
End If
End Function
End Class
The problem arrives when trying to binary serialize these kind of objects, since this shared field is nos being properly stored and returns to its default value when deserializing.
I suppose this is the expected behaviour, so my question is... how can I make a shared field persistent? I have read some comments to similar questions that say that this is a bad design, but it really makes sense (AFAIK) in my case, since this variable should be the same to all the object, but can be changed by the user and therefore should be stored.
Can you suggest another way of doing it?
Thanks!
What you have read, in my opinion, is correct. This is, likely, a bad design. However, if you must, there are two ways to do this with the XmlSerializer. The easy way would be to simply add a public instance (non-shared) property which has a getter and setter which simply wrap the shared property, for instance:
Public MustInherit Class NitrogenController
Public Shared Property ControlInterval As TimeSpan
Public Property CurrentControlInterval() As TimeSpan
Get
Return ControlInterval
End Get
Set(value As TimeSpan)
ControlInterval = value
End Set
End Property
End Class
If you aren't satisfied with that method, the second, more involved, option would be to override the default serialization logic by implementing the ISerializable interface.

How to bind to Class using Generics in XAML

I have created a simple class like this one...
Public Class Localizer(Of T)
Public Shared ReadOnly Property DisplayName(ByVal propertyName As String) As String
Get
...
End Get
End Property
End Class
And I'm attempting to bind to it in XAML something like this...
Header="{x:Static loc:Localizer(Of AircraftReference).DisplayName [IsMilitary]}"
But this must not be the right syntax. This may not even be possible.
There are two problems here.
XAML support for generics is not complete; I don't think you can specify the type parameter in XAML.
However, there's an easy workaround for this problem:
Public Class Localizer(Of T)
Public Shared ReadOnly Property DisplayName As String
Get
...
End Get
End Property
End Class
Public Class AircraftReferenceLocalizer
Inherits Localizer(Of AircraftReference)
End Class
Now you can use:
Header="{x:Static loc:AircraftReferenceLocalizer.DisplayName}"
x:Static does not support parameterized properties, so you cannot pass the string "IsMilitary". I'm afraid you'll have to find a solution without x:Static. It might make sense to describe want problem you want to solve and ask for a solution in a new question.

Auto Property with public getter and private setter

NOTE: This is not a duplicate of VB.NET equivalent of C# property shorthand?. This question is about how to have different access rights on getter and setter of a VB auto-property; e.g public getter and private setter. That question is about the syntax for auto-property (and does not mention this issue).
I am trying to convert an auto Property (public getter and private setter) from C# to VB.NET.
But after conversion VB.NET is maintaining a private field.
C# code
class DemoViewModel
{
DemoViewModel (){ AddCommand = new RelayCommand(); }
public ICommand AddCommand {get;private set;}
}
VB.NET equivalent from code converter is
Class DemoViewModel
Private Sub New()
AddCommand = New RelayCommand()
End Sub
Public Property AddCommand() As ICommand
Get
Return m_AddCommand
End Get
Private Set
m_AddCommand = Value
End Set
End Property
Private m_AddCommand As ICommand
End Class
VB.NET code generates private backing field.
Is it possible to get rid of this back field in source code (like c#)? How?
Without this feature, VB.NET source will have lots of such redundancy.
Using VB.NET, if you want to specify different accessibility for the Get and Set procedure, then you cannot use an auto-implemented property and must instead use standard, or expanded, property syntax.
Read MSDN: https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/auto-implemented-properties
If getter and setter have same accessibility, e.g. both are Public, then you can use the auto-property syntax, e.g.:
Public Property Prop2 As String = "Empty"
In VB.NET it's
Public ReadOnly Property Value As String
Then to access the private setter, you use an underscore before your property name
Me._Value = "Fred"
since the answer(s) above hold(s), you may introduce a Public Prop to expose the Private one. This may not be a nice solution but still less code, than expanded Property syntax
Private Property internalprop as object
Public Readonly Property exposedprop as Object = internalprop

Error using multiple Generic Classes in VB.Net

I tried to find a similar issue already posted but simply got confused with what i found.
I have a situation which involves the following objects:-
Reports contain parameters
Documents contain parameters
Report and Document Parameters are similar
Queries contain parameters
Reports, Documents and Queries all have similar Parameters
So I created the following class structure:-
Public MustInherit Class clsBaseCollection(Of TclsBaseChild As clsBase, TclsBaseParent As clsBase)
Public MustInherit Class clsParams(Of TclsParam As clsParam, TclsRootObject As clsRootObject)
Inherits clsBaseCollection(Of TclsParam, TclsRootObject)
Public MustInherit Class clsRepDocParams(Of TclsRepDocParam As clsRepDocParam, TclsReportDocument As clsReportDocument)
Inherits clsParams(Of TclsRepDocParam, TclsReportDocument)
Public Class clsReportParams
Inherits clsRepDocParams(Of clsReportParam, clsReport)
Public MustInherit Class clsReportDocument
MustOverride ReadOnly Property Parameters() As clsRepDocParams(Of clsRepDocParam,clsReportDocument)
Public Class clsReport
Inherits clsReportDocument
Private _Params As clsReportParams
Public Overrides ReadOnly Property Parameters() As clsReportParams
Get
If _Params Is Nothing Then
BeginUpdate()
_Params = New clsReportParams(Me)
EndUpdate()
End If
Return _Params
End Get
End Property
The last property produces the following error:-
‘Public Overrides ReadOnly Property Parameters As clsReportParams' cannot override 'Public MustOverride ReadOnly Property Parameters As clsRepDocParams(Of clsRepDocParam, clsReportDocument)' because they differ by their return types.
I cant see how this is so because I believe I have my classing levels correct!?
Apologies for the lack of tab formatting... im new to the stack overflow site and hopefully i will improve ;)
Cheers
Jeff
The MustOverride property is declared as
As clsRepDocParams(Of clsRepDocParam,clsReportDocument)
Your Override is simply declared as
As clsReportParams
It does not specify the base collection so they do not match. You should probably declare the override as
As clsRepDocParams(Of clsRepDocParam,clsReportDocument)
to match the base class.
It is worth noting that with every additional level of inheritance that you create, you need to be that much more careful to ensure that you design is done very carefully! If I was reviewing that code I would need to be convinced that the complexity was actually going to pay off over the lifetime of the project.

After restricting Setter scope and then applying an interface, scope is disregarded!

If I set a Friend-level scope on a setter, like this...
Public Class MyClass
Public Property IsDirty() As Boolean
Get
Return _isDirty
End Get
Friend Set(ByVal trueFalse As Boolean)
_isDirty = trueFalse
End Set
End Property
End Class
...And then call it from another project, it works correctly. I can't do something like MyClass.IsDirty = True.
Great! That's exactly what I want.
But now if I define an interface, and I will indeed have to do that:
Public Interface IMyClass
Property IsDirty() As Boolean
End Interface
I can do something like:
Dim MyInstance as IMyClass= GetSomeInstanceOfMyClass()
MyInstance.IsDirty=True
...And, bizarrely, it runs! No exceptions are thrown, and the inner variable is set to True. It ignores the Friend scope completely!
That's hideous. What am I missing??
Note: I need this because I'm designing an API, and I want the inner API to be able to set IsDirty, but end-developers shouldn't be able to get into that. Currently I am wrapping the whole class in a facade to get this functionality, but the facade should be unecessary.
Interface methods always have public accessibility. You can't fix that by explicit interface implementation, that will only hide the class method. Simply casting the object to the interface type gives unfettered access again.
EDIT: actually, the problem is easy to solve. Just declare the property ReadOnly in the interface declaration :)
For example:
Public Interface IMyClass
ReadOnly Property IsDirty() As Boolean
End Interface
Public Class Test
Implements IMyClass
Private mIsDirty As Boolean
Private ReadOnly Property IsDirtyImpl() As Boolean Implements IMyClass.IsDirty
Get
Return mIsDirty
End Get
End Property
Public Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
Friend Set(ByVal value As Boolean)
mIsDirty = value
End Set
End Property
End Class
What you are missing is the concept of inplicit and explicit interface implementation. See the answer to this question for more details.
And if you think it's hideous with a Friend setter, try setting it to Private and watch it still be accessible via the interface!