VB.net 2008 Property Array - vb.net

Hi can anyone help here? I am currently learning VB.net but for a project I need to create and array and pass it using a property. The data to be passed will be a train's destination, the time its due and the expected time of the train. I was wondering if someone could simplly explain how to first produce an array and then show how to pass it to a custom control using a property any help would be great.
Thank you.

If you want to provide multiple values to a control, one clean way to do this is to have separate properties, one for each value, instead of trying to pass them all in one array. Another clean way to do this is to create a new class (type) that combines all these values into one structure, and expose a single property of that type. For example:
Public Class TrainDetails
Private _destination As String
Private _due As DateTime
Private _expected as DateTime
Public Property Destination As String
Get
Return _destination
End Get
Set
_destination = Value
End Set
End Property
Public Property Due As DateTime
Get
Return _due
End Get
Set
_due = Value
End Set
End Property
Public Property Expected As DateTime
Get
Return _expected
End Get
Set
_expected = Value
End Set
End Property
End Class
(Note, I think it's necessary to implement property procedures instead of directly exposing the internal field values in order for the properties to show up in a property grid.)
So if you have this class, then you can create a property of type TrainDetails on your control that will encapsulate all these properties in one value. I think they will be editable in the property grid as a single property with an expandable "+" next to it to edit the individual values.

Related

Accessing an element of a custom type list by property value

Let's say I have a class called ControlInfo, which has the following properties:
Public Property Control As Control
Public Property ControlState As Int32
Now I want to create a method for accessing a specific instance of ControlInfo from a List, so I do this:
Public Function GetInstance(control As Control) As ControlInfo
For Each c As ControlInfo In list
If c.Control.Name = control.Name Then
Return c
End If
Next
Return Nothing
End Function
Is there a better way to access specific instance from a list of a custom class based on its property value? Is the loop approach bad for performance?
Sidenote: I have also considered the implementation of a Dictionary other than a List (so I would access an instance via a key, which can be a lot better than looping through all the values), but I feel that if I resort to that I would be avoiding a problem instead of solving it. Maybe I am being paranoid but I would like to know other valid approaches here, and be more certain of what should/shouldn't be done.
Thanks.

Advantages of Properties in Classes

I've been using classes for a while now, but I feel I may have been using them incorrectly.
When I create the properties for the class, I just use public variables so I end up with something like the following:
Class clsMyClass
Public Name As String
End Class
However, I've been reading some info on the net and they suggest that it should be set up in the following way:
Class clsMyClass
Private Name As String
Property UsersName() As String
Get
Return Name
End Get
Set(ByVal Value As String)
Name = Value
End Set
End Property
End Class
Is the way I'm doing it extremely incorrect? If so, why? I feel like the second method adds some sort of security but to be honest, it just looks like unnecessary code..?
One advantage of properties is that they let you customise the access to your private fields and enable you to do more so you can do the following (examples, it's not limited to that):
Make a property read-only for public access
Raise an even when a property is updated
Update other private fields when a property is updated
Validate the value that is being set
See below advantages of Properties over Variables from the C# in Depth article:
• There's more fine-grained access control with properties. Need it to be publicly gettable but really only want it set with protected access? No problem (from C# 2 onwards, at least).
• Want to break into the debugger whenever the value changes? Just add a breakpoint in the setter.
• Want to log all access? Just add logging to the getter.
• Properties are used for data binding; fields aren't.
Few other points:
1) You can also make properties read-only so no one from outside the class set the values but can fetch it.
2) You can do certain actions in the get and set. i.e. Append a prefix anytime set is called
3) You can also use auto-implemented property to minimize code like below:
Public Property Name As String
You are not doing anything wrong. Properties give you a shorthand basically, a syntactic sugar.
You can still use a backing private variable and do logic in get and set if you have to while using properties. Even better is the private/protected set or get, which is again another syntactic sugar so that you won't have to write all the code manually.
First of all, VB.NET allows you to use this syntax (called shorthand property declaration - I believe since VS 2010):
Public Property Name As String
Not so much different from this (called field declaration):
Public Name As String
Second, Microsoft data binding does not work well with fields. Try this example (see below).
Example. Put a listbox called ListBox1 (default name) and a button called Button1 on an empty form in an empty WinForms project. Replace your form code with this:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lst As New List(Of clsMyClass)
lst.Add(New clsMyClass)
ListBox1.ValueMember = "Name"
ListBox1.DisplayMember = "Name"
ListBox1.DataSource = lst
End Sub
End Class
Class clsMyClass
Public Property Name As String = "Hello"
End Class
Start the application and notice that a listbox is populated with one entry, Hello. This proves that binding worked correctly. Now replace your property declaration with a field declaration instead. Start your application one more time and notice that a listbox is showing your class type converted to String. It means that your field binding did not work, and default binding was used instead, where DisplayMember is assigned sort of classInstance.ToString().
If you are curious to learn more about what happens behind the scenes, you can put a breakpoint on .DataSource assignment, and see how DisplayMember gets reset or keeps its value depending on whether you are using fields or properties.

Should I create individual properties in a class or just a method to set the values?

I am learning vb.net and I am having trouble wrapping my head around the following...
I can create several properties of a custom class and get/set values or I can create a method to set them all at once. If each property is going to allow read and write should I just make a method to assign values all at once? I assume that I am missing a very important piece here. Example:
I can create 2 properties:
Public Class Employee
Public Property LastName as string
Get
Return strLastName
End get
Set(ByVal value as string)
strLastName= value
End Set
End Property
Public Property FirstName as string
Get
Return strFirstName
End get
Set(ByVal value as string)
strFirstName= value
End Set
End Property
End Class
or I can create a method:
Public Class Employee
Public Sub AddEmployee(ByVal strLastName, ByVal strFirstName)
LastName = strLastName
FirstName = strFirstName
End Sub
End Class
I apologize for such a noob question, but any insight is greatly appreciated. thank you!
If you only have a single method, you will have to use it even if you only want to change the value of a single field.
Additionally, in such a method, if you need to validate the input, you will need to write quite a lot of code for validation that is not relevant to all of the fields.
If values must be updated together, use a method to update them together and do not provide setters.
The reality of things is that how to do this depends on what you are modelling in your class. There are no hard and fast rules that say that properties are better than methods or vice versa.
There is no reason not to support both properties and a method that sets multiple properties.
Commonly, a constructor is used to create an instance of the class and to set some properties. In VB, naming a class method "New" defines it as a constructor. In your example, if you rename your AddEmployeee method to New, you will have a perfectly fine constructor. Then you program can create new instances as such:
Dim emp1 as New Employee("Burdell", "George")

Why can't define get type and set type distinctly within Properties?

Here is the problem, I wanted to define a property which accepts decimal numbers and do some process on the value and return string such as the below:
Public Property Amount() As String
Get
Return Utility.PaddingRight(Me.msAmount.ToString(), 10)
End Get
Set(ByVal vsValue As Decimal)
Me.msAmount = vsValue
End Set
End Property
But compilers warns "Set parameters must have the same type of the containing property."
It doesn't look like it should throws an error since it looks legit.
The reason that you can't is because what you put into a property should be exactly the same as what you get out of it. If the type changed then this condition would never be true. Microsoft's spec says that "Properties are like smart fields". Imagine if a field (class variable) changed between reading and writing.
Your goal is completely valid but that's not the intended use for properties. (By "intended goal" I mean Microsoft's intended goal.) Your design would also opens doors for potential problems if an invalid or null string were passed in. One of the design goals for properties is that they are light weight and shouldn't throw errors. They can but shouldn't. The recommended solution is to use the TryParse pattern for your property.
EDIT
Sorry, my brain was sidetracked, your goal is changing the getter, not the setter. The pattern that you're looking for is just a read-only property (as #msarchet pointed out) that's specific to your getter. For instance, AmountForPrint or something. You should still include a read/write for your actual value, too.
Public ReadOnly Property AmountForPrint
Get
Return Me.Amount.ToString()
End Get
End Property
Public Property Amount As Integer
Get
End Get
Set(value As Integer)
End Set
End Property
I think you need a to do this with a method not a property
Public Function Amount(ByVal value As Decimal) As String
End Function
This is just a shot in the dark . . .
Set(ByVal vsValue As String)
Me.msAmount = System.Convert.ToDecimal(vsValue)
End Set
You'd be far better off doing this as such
Public Read Only Property Amount() As String
Get
Return Utility.PaddingRight(Me.msAmount.ToString(), 10)
End Get
End Property
Public Sub SetAmount(ByVal value As Decimal)
Me.msAmount = value
End Sub

Is it correct to correct properties values on the fly?

Is it correct to correct properties values on the fly?
for example: (note the .ToLower)
Public Property X() As String
Get
Return _x.ToLower
End Get
Set(ByVal Value As String)
_x = value.ToLower
End Set
End Property
There is nothing incorrect about standardizing your properties in getter/setters. Without any context of what X represents it is hard determine if a property is the right way to access and update the value of X. Depending on the application, it might make sense to not have a public setter at all but instead have a method such as CustomerRequestedXToChange(XUpdatedValue as String)
Some improvements to your code though:
Be sure that _x is private so that no other classes can modify the value.
Only perform ToLower on the setter, not both. As long as you follow the next convention that should work fine.
All calls to _x within this class should go through X, that way the value of _x will be correct.