Class with public properties as list of structures for saving a communcation protocol - vb.net

I want to save a communication inside a class. After that I plan to serialize the class o a XML file, where all datapoints are decoded between a tag.
Therefore I want to explain my communication protocol first.
The message Frame Looks like the following
LIE01
LIE02
When the communication ends, I have around 3000 of this telegrams inside a raw variable.
Here I describe the Messages:
LIE01: Header + 1 data word
LIE02: Header + 2 data words
My idea was to decode the frame and save it in a list (or array) of structures that are public properties of my class.
Public Class Com
Public Structure sLIE01
Public Property Header As Int16
Public Property data1 As Int16
End Structure
Public Structure sLIE02
Public Property Header As Int16
Public Property data1 As Int16
Public Property data2 As Int16
End Structure
Public Property LIE01 As List(Of sLIE01)
Get
?
End Get
Set(ByVal value As List(Of sLIE01))
?
End Set
End Property
Public Property LIE02 As List(Of sLIE02)
Get
?
End Get
Set(ByVal value As List(Of sLIE02))
?
End Set
End Property
End Class
Unfortunatelly I am more a beginner than an expert, so that I have no idea, how to write the code to Set or Get a specific LIE message.
Even I'm not sure, whether my way is a common way for this purpose or not.

You could use auto implemented properties in your code and skip getters and setters altogether (https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/auto-implemented-properties). You'll then be able to assign lists to them like:
Dim newList as new List(of sLIE01)()
ComInstance.Lie01 = newList
You can also operate on those list properties directly (just make sure you initialize them in class constructor to avoid NullReferenceException):
Dim lie as sLie01
ComInstance.Lie01.Add(lie)
Also consider replacing structures with classes: https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/structures-and-classes

If you still want to use Get Set it would look like this...
Private _LIE01 As List(Of sLIE01)
Public Property LIE01 As List(Of sLIE01)
Get
Return _LIE01
End Get
Set(value as List(Of sLIE01))
_LIE01 = value
End Set
End Property

Related

How to sort a custom list - SecondaryItem within PrimaryItem

Hi there have a list of custom objects that I need to be able to sort, one property within another. How do I go about doing this using .Net. Normally I would carry out all sorting requirements within the SQL that delivers the data, unfortunately in this case I don't have control over that generation of the raw data. I consequently have no experience of sorting content using .Net functions such as Linq and/or IComparable. An impression of the code elements involved are listed below:
Public Class CustomObject
Public Property PrimaryItem As String
Get
Return _primaryItem
End Get
Set(ByVal value As String)
_primaryItem = value
End Set
End Property
Public Property SecondaryItem As String
Get
Return _secondaryItem
End Get
Set(ByVal value As String)
_secondaryItem = value
End Set
End Property
End Class
Public Class CustomObjectList
Inherits List(Of CustomObject)
Public Sub New()
End Sub
End Class
In essence I want to be able to sort CustomObjectList according to SecondaryItem within PrimaryItem:
PrimaryItem1
SecondaryItem1
SecondaryItem2
etc...
PrimaryItem2
SecondaryItem1
SecondaryItem2
etc...
etc...
Hoping that some kind person will be able to give me a 'leg up' in usage of either Linq and/or iComparable.
Dim result = MyList.OrderBy(Function(x) x.PrimaryItem).ThenBy(Function(x) x.SecondaryItem)

Reference to an attribute of a class by means of a string containing the name of the property

Let's take a very short example of a class like this:
Public Class The_Class1
Public Property ID As Integer
Public Property Property1_Integer As Integer
Public Property Property2_Single As Single
End Class
Somewhere else, I have a dictionary containing instances of The_Class1, like this:
Public Dictionary_Class1 As New Dictionary(Of Integer, The_Class1)
I want to perform an operation over Property1_Integer on all of the members inside Dictionary_Class1. Also, I want to perform the very same operation over Property2_Single, so I would like to create a function to perform such operation, and somehow instruct VB to use a given property on every call.
Can you think of an elegant way to do that?
Edit: Let's say, for example, that the operation that I want to perform is the sum of every Property1_Integer or Property2_Single of the members inside the dictionary. What I really really want to do is to determine if all of the values are the same, or if there is at least one that is different.
You can use Reflection, but it's not as clean as you may imagine. Here's some skeleton code you can adapt to your needs:
Public Class The_Class1
Public Property ID As Integer
Public Property Property1_Integer As Integer
Public Property Property2_Single As Single
End Class
Private Sub SetProperty1_Integer()
Dim myClassInstance As New The_Class1
Dim myType As Type = GetType(The_Class1)
Dim propertyInfo As System.Reflection.PropertyInfo = myType.GetProperty("Property1_Integer")
propertyInfo.SetValue(myClassInstance, 1)
MessageBox.Show(myClassInstance.Property1_Integer.ToString)
End Sub
Have fun!

How to instantiate Class object with varying number of property values

Been working a lot with custom classes lately and I love the power you can have with them but I have come across something that I'm not able to solve and/or find anything helpful online.
I have a list of a class with properties I'm looking to only store information pulled from a database into.
Public Class CustomClass
Public _Values As String
Public _Variables As String
Public ReadOnly Property Values() As String
Get
Return _Values
End Get
End Property
Public ReadOnly Property Variables() As String
Get
Return _Variables
End Get
End Property
Sub New(ByVal values As String, ByVal variables As String)
_Values = values
_Variables = variables
End Sub
End Class
I will be iterating through some database entries, and I'm looking to store them into the appropriate property when I hit them (since I won't have them all available immediately, which is part of my problem). I want to just be able to add either the value or the variable at a time and not both of them, but since I have the sub procedure 'New' passing two arguments, it will always require passing them both. I've found the only way around this is by making them optional fields which I don't feel is the right way to solve this. Is what I'm looking to do possible with a class or would it be simpler by using a structure?
You can overload the constructor:
Friend Class Foo
' using auto-implement props:
Public Property Name As String ' creates a _Name backing field
Public Property Value as Integer
Public Sub New(newN as String, newV as Integer)
' access "hidden" backing fields if you want:
_Name = newN
_Value = newV
End Sub
Public Sub New() ' simple ctor
End Sub
Public Sub New(justName As String)
' via the prop
Name = justName
End Sub
End Class
You now have 3 ways to create the object: with full initialization, partial (name only) or as a blank object. You will often need a "simple constructor" - one with no params - for other purposes: serializers, Collection editors and the like will have no idea how to use the parameterized constructors and will require a simple one.
If rules in the App were that there was no reason for a MyFoo to ever exist unless both Name and Value being defined, implementing only the New(String, Integer) ctor enforces that rule. That is, it is first about the app rules, then about coding convenience.
Dim myFoo As New Foo ' empty one
myFoo.Name = "ziggy" ' we only know part of it
Since the default of string is nothing, you could pass nothing for the value you don't have. IE
Collection.Add(New CustomClass("My Value",Nothing))
Every type has a default, so this works with more than just strings.

How to use instance of New Object in With... Block

Dim objects As New List(Of Object)
With New Object
.prop1 = "Property 1"
.prop2 = "Property 2"
objects.add(.instance) 'i mean instance of New Object
End With
is it possible.
I ask new question because last question has mislead information and I don't give right answer. so here code.
No it is not possible. The With statement basically creates an implicit variable. All you can do with that variable is access members and there is no member that returns a reference to the object itself.
If you want succinct code to create, populate and add an object to a list then do this:
myList.Add(New SomeType With {.SomeProperty = someValue,
.SomeOtherProperty = someOtherValue})
Interestingly, you can make it work the way you wanted if you create your own extension method. I was under the impression that you could not extend the Object class but either I was wrong or that has changed because I just tried in VB 2013 and it worked. You can write a method like this:
Imports System.Runtime.CompilerServices
Public Module ObjectExtensions
<Extension>
Public Function Self(Of T)(source As T) As T
Return source
End Function
End Module
and then do something like this:
With New SomeType
.SomeProperty = someValue
.SomeOtherProperty = someOtherValue
myList.Add(.Self())
End With
I'm not sure that that really provides any benefit though, given the availability of the object initialiser syntax that I demonstrated first.
Hmmm... I just realised that that's not actually extending the Object class. It was my original intention to try to do so but then I realised that a generic method was better because it would then return the same type as you call it on. I did just test it with a non-generic method extending type Object and it did still worked though.
You should to create your own class By example :
Public Class Car
Private _NumberCar As Integer
Public Property NumberCar() As Integer
Get
Return _NumberCar
End Get
Set(ByVal value As Integer)
_NumberCar = value
End Set
End Property
Private _ColorCar As Color
Public Property ColorCar() As Color
Get
Return _ColorCar
End Get
Set(ByVal value As Color)
_ColorCar = value
End Set
End Property
Private _OwnerName As String
Public Property OwnerName() As String
Get
Return _OwnerName
End Get
Set(ByVal value As String)
_OwnerName = value
End Set
End Property
End Class
and in the Class where you want to add the cars object do this :
Dim CarList As New List(Of Car)
Dim item As New Car
With item
.NumberCar = 1243
.ColorCar = Color.Red
.OwnerName = "Ibra"
End With
CarList.Add(item)
strong text

How to iterate through a property of a class in VB?

If I have a class object A, and it has properties such as a0, a1, a2... If this class has 100 properties like this (up to a99). I would like to display each of these properties, but I do not want to have 100 lines of code of calling this as following
print A.a0
print A.a1
print A.a2
...
print A.a99
The code is too inefficient, so I am wondering if there is a way to loop through these properties. Thank you.
.NET provides the ability to examine an object at runtime through a process known as reflection. The purpose of the original post was to iterate through an object's properties in an automated fashion rather than by manually coding explicit statements that displayed each property, and reflection is a process to accomplish this very thing.
For this particular purpose, looping through an object's properties at run-time, you use the GetProperties() method that is available for each Type. In your case, the Type you want to "reflect" is A, so the type-specific version of GetProperties returns a list of the instance properties for that object.
When you ask .NET to return the properties of an object, you can also specify what's called a binding flag that tells .NET which properties to return - public properties, private properties, static properties - a myriad of combinations from about twenty different values in the BindingFlags enumeration. For the purposes of this illustration, BindingFlags.Public will suffice, assuming your A0-A999 properties are declared to be public. To expose even more properties, simply combine multiple BindingFlag values with a logical "or".
So, now armed with that information, all we need to do is create a class, declare its properties, and tell Reflection to enumerate the properties for us. Assuming your Class A exists with property names A0-A999 already defined, here's how you'd enumerate ones starting with "A":
// Assuming Class "A" exists, and we have an instance of "A" held in
// a variable ActualA...
using System.Reflection
// The GetProperties method returns an array of PropertyInfo objects...
PropertyInfo[] properties = typeof(ActualA).GetProperties(BindingFlags.Public);
// Now, just iterate through them.
foreach(PropertyInfo property in properties)
{
if (property.Name.StartsWith("A")){
// use .Name, .GetValue methods/props to get interesting info from each property.
Console.WriteLine("Property {0}={1}",property.Name,
property.GetValue(ActualA,null));
}
}
There you have it. That's C# version rather than VB, but I think the general concepts should translate fairly readily. I hope that helps!
This MSDN code sample illustrates how to iterate over a class's properties using reflection:
http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx#Y900
Create a VB.Net Console application, copy and paste this code into the Module1.vb file and run it.
Module Module1
Sub Main()
For Each prop In GetType(TestClass).GetProperties()
Console.WriteLine(prop.Name)
Next
Console.ReadKey(True)
End Sub
End Module
Public Class TestClass
Private _One As String = "1"
Public Property One() As String
Get
Return _One
End Get
Set(ByVal value As String)
_One = value
End Set
End Property
Private _Two As Integer = 2
Public Property Two() As Integer
Get
Return _Two
End Get
Set(ByVal value As Integer)
_Two = value
End Set
End Property
Private _Three As Double = 3.1415927
Public Property Three() As Double
Get
Return _Three
End Get
Set(ByVal value As Double)
_Three = value
End Set
End Property
Private _Four As Decimal = 4.4D
Public Property Four() As Decimal
Get
Return _Four
End Get
Set(ByVal value As Decimal)
_Four = value
End Set
End Property
End Class