Auto-implemented property in VB.NET with a protected setter? - vb.net

So far I had a read-only property in VB.NET as
Public ReadOnly Property Username() As String
Now I need to make changes to my code as the setter to this property needs to be protected. In C# I would have done:
public string Username {get; protected set;}
But I can't find such a short hand and good-looking solution in VB.NET. Does VB.NET provide that and I am unaware of this? Or do I have to write so much code and make it look little uglier?
Public Property Username() As String
Get
Return m_Username
End Get
Protected Set
m_Username = Value
End Set
End Property
Private m_Username As String
It's going to make my class so dirty if I had 20 properties and set them like this.

Unfortunately, there is no such shorthand syntax in VB. Also see: https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/auto-implemented-properties

You could make your code a bit shorter by doing it like this:
Protected _username As String
Public ReadOnly Property Username As String
Get
Return _username
End Get
End Property
That way you can set the username through _username in classes that inherit this class.

Related

Newsoft JSON .NET Deserializing to an Object with Private Properties in VB.net

I am currently writing an API which is taking objects from a web service handling it in VB.net using the Newsoft JSON .NET library.
I'm deserializing a JSON array called Vehicles into a list of vehicles.
Here is the important code snippets:
Public Class VehicleList
Public Vehicles() As Vehicle
End Class
Public Class Vehicle
Public Property licence_plate_number As String
End Class
Here we have a web client that grabs the json and put it into the objects.
Public Class dcVehicles
Private Property _Vehicles As VehicleList
Public ReadOnly Property Vehicle As Vehicle()
Get
Return _Vehicles.Vehicles
End Get
End Property
Public Sub Refresh()
_Vehicles = JsonConvert.DeserializeObject(Of VehicleList)(wcReply, jsSettings)
End Sub
End Class
There's slightly more to it (cut it down).
So everything is working as intended, json net is creating an array of vehicles.
I'm trying to achieve this with the properties in the vehicle class as private and read only, the applications using the api should not be able to set these.
The problem is I've tried changing the public property in the vehicle class to keep the property private and allow readonly as below:
Public Class Vehicle
Friend Property licence_plate_number As String
Public ReadOnly Property RegistrationNumber As String
Get
Return licence_plate_number
End Get
End Property
End Class
The problem I then get is that JSON.net is unable to populate the vehicles. All 3 classes are in the same namespace.
So I tried licence_plate_number with the Friend/private access level modifier but still Json net is unable to populate the object.
The only way is keeping it as Public.
Does anyone have an idea for a work-around? Or is am I missing something simple?
Thanks
If you just want to serialize a Private or Friend property with Json.NET, mark it with <JsonProperty> and mark the public readonly property you don't want to serialize with <JsonIgnore>:
Public Class Vehicle
<JsonProperty> _
Friend Property licence_plate_number As String
<JsonIgnore> _
Public ReadOnly Property RegistrationNumber As String
Get
Return licence_plate_number
End Get
End Property
End Class
Demo fiddle.
But if you really want read-only value semantics for the licence_plate_number property so that it cannot be set after construction, you can do this by replacing the default constructor with a single parameterized constructor and matching the constructor argument names to the JSON property names, like so:
Public Class Vehicle
Private Readonly licence_plate_number As String
Public Sub New(ByVal licence_plate_number as String)
Me.licence_plate_number = licence_plate_number
End Sub
<JsonProperty("licence_plate_number")> _
Public ReadOnly Property RegistrationNumber As String
Get
Return licence_plate_number
End Get
End Property
End Class
When there is a single public constructor that is parameterized, Json.NET will call it, matching the constructor arguments to the JSON properties by name using reflection and using default values for missing properties. Matching by name is case-insensitive, unless there are multiple matches that differ only in case, in which case the match becomes case sensitive.
Demo fiddle.
If your class has multiple public constructors, mark the one to use with <JsonConstructor>.

Is there a keyword that can make a class variable readonly from outside the class but not on the inside?

Basically, the readonly keyword doesn't let me modify a field after I first create the class instance. I could use a property but in this case its just extra overhead. Is there a keyword to make a class field readonly from only outside the class?
make the field private, provide getter and setter for it.
Make the setter private.
This way the value can be seen from outside the class by the getter,but, cannot be set/written from outside the class.
this makes the property read-only from outside the class.
As others have stated, use a property. If you don't want to split the property into one Getter and one Setter then make the setter private.
Public Class Foo
Public Property Abc() As Object
Get
Return Me.m_Abc
End Get
Private Set(value As Object)
Me.m_Abc = value
End Set
End Property
Private m_Abc As Object
End Class
However: The common way is to set the access level of the field to Friend making it accessible within the same assembly, but not from outside the assembly.
Public Class Foo
Public ReadOnly Property Abc() As Object
Get
Return Me.m_Abc
End Get
End Property
Friend m_Abc As Object
End Class
No there isn't. This type is scenario is precisely why properties are provided in the first place. You get a whole lot of flexibility.
However, if you insist you want to use a read only field, you can use reflection to change the value:-
Public Class TestClass
Public ReadOnly MyNumber As Integer
Public Sub New()
'Readonly fields can only be changed this way
'in the constructor
Me.MyNumber = 900
End Sub
Public Sub ChangeNumber(ByVal num As Integer)
SetNumber(num)
End Sub
Private Sub SetNumber(ByVal num As Integer)
Dim fi = Me.GetType.GetField("MyNumber")
'Reflection can change the value of
'a read only field after construction
fi.SetValue(Me, num)
End Sub
End Class
Note that this is a very terrible thing. Reflection shouldn't be used for this sort of thing as you're going to take a performance hit. Just use properties and save yourself the trouble.

VB.Net Create Database table from class property

I'm trying to create an inheritable class(OF t) in vb.net that I will pass it a class of objects. Inside the class of objects I want to use the class properties to create a corresponding database table. Like below
Public Class SampleClass
#Region "Properties"
Private newPropertyValue As String
Public Property NewProperty() As String
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
#End Region
Public Sub New()
End Sub
End Class
I'm new to vb.net so I don't know my way around exactly.
I was looking into class attributes for this action but they do not fully make sense to me yet. Thanks in advance.
You will want to get well versed on something called Code First. This should get you started.

Override Public Readonly property

Having a bit of a brain fart, right before bed. But i have the need to remap a ReadOnly Property from one name to a specified name i want.
I figured i could do
Public Readonly Property DocName as String
Get
Return Mybase.Name
End Get
End Property
And yes i am trying to remap the Name Property for an XMLDocument object. Just want to make sure that as long as i declare this property and then type:
Public Overrides ReadOnly Property Name As String
Get
Return SomeValue
End Get
End Property
I will be good togo? I know i will get the method has multiple definitions with identical signatures message, which brings me to my 2nd Question:
How do i prevent the Multiple Signatures error message from popping up with this type of declaration?
Unless i am missing some declaration attribute for this type of override.
You can use Shadows to accomplish this:
Public Class A
Public ReadOnly Property Name As String
Get
Return "Name"
End Get
End Property
End Class
Public Class B
Inherits A
Public ReadOnly Property DocName As String
Get
Return MyBase.Name
End Get
End Property
Public Shadows ReadOnly Property Name As String
Get
Return "SomeValue"
End Get
End Property
End Class

VB.Net Properties - Public Get, Private Set

I figured I would ask... but is there a way to have the Get part of a property available as public, but keep the set as private?
Otherwise I am thinking I need two properties or a property and a method, just figured this would be cleaner.
Yes, quite straight forward:
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
I'm not sure what the minimum required version of Visual Studio is, but in VS2015 you can use
Public ReadOnly Property Name As String
It is read-only for public access but can be privately modified using _Name
Public Property Name() As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
One additional tweak worth mentioning: I'm not sure if this is a .NET 4.0 or Visual Studio 2010 feature, but if you're using both you don't need to declare the value parameter for the setter/mutator block of code:
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Private Set
_name = value
End Set
End Property
I find marking the property as readonly cleaner than the above answers. I believe vb14 is required.
Private _Name As String
Public ReadOnly Property Name() As String
Get
Return _Name
End Get
End Property
This can be condensed to
Public ReadOnly Property Name As String
https://msdn.microsoft.com/en-us/library/dd293589.aspx?f=255&MSPPError=-2147217396
If you are using VS2010 or later it is even easier than that
Public Property Name as String
You get the private properties and Get/Set completely for free!
see this blog post: Scott Gu's Blog