Generics question. Do I need reflection to answer this? - vb.net

Public Class B
End Class
Public Class D
Inherits B
End Class
Public Class SomeClass
Public Shared Sub SomeFunction2(Of TGeneric As B)()
'Is there a way that I can tell whether the the Type used
'as TGeneric is of type "B" or "D" without having
'an instance of a class also passed in?
'Reflection? How?
End Sub
End Class
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SomeClass.SomeFunction2(Of D)()
End Sub
End Class

That depends on what you mean by "is of type B or D".
If you only want to differentiate between someone actually calling SomeFunction2(Of B) and SomeFunction2(Of AnyTypeThatInheritsFromB), then you can just do:
If GetType(B) Is GetType(TGeneric) Then
... they passed in B
Else
... they passed in a subclass
End If
But this seems like a bit of a code smell. Generics are intended for you not to care what the actual type is. What's the reason you need to know?

Related

How to change the value of a global variable inside a sub in vb.net

Is there any way for me to change the value of a global variable through say an if else statement inside a sub in vb.net
Public Class stuff
Public Shared C As Integer
end class
Public class other stuff
Private Sub C5pts_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles C5pts.CheckedChanged
If C5pts.Checked Then
End If
End Sub
end class
I'm trying to change the value of C in this if then statement but I'm confused as to how.
Yes you can :
If C5pts.Checked Then
Stuff.C = 123
End if

vb.net class reloads when a subroutine is classed from another class

My vb.net program loads with ClassA. During program run, i call a Class B that makes some processes. during ClassB processing , it call a subroutine into ClassA (Main program form class), but when i do this , i found that the whole initialization of the class A occurs again, ie, the DECLARATION of class variables starts again, and the NEW subroutine occurs again.
- NB : This only occurs if I run Class B from a backgroundworker. If
ClassB was called from Form1 Main Thread, this error does not appear.
here is the code :
Public Class Form1
Dim g As String = "adsfadsf"
Public Sub New()
InitializeComponent()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim clsB As New ClassB
clsB.st()
End Sub
Public Sub UpdateView()
' do update here
End Sub
End Class
Public Class ClassB
Public Sub st()
Form1.UpdateView()
End Sub
End Class
Any feedback ?
It seems that background worker is the issue since it loses reference to the parent thread. A workaround it's to pass A reference to the main thread, then use this reference to call the specific subroutine
I tried out and worked perfectly
Any code? (Can't add a comment yet :/).
You might be declaring a new instance of ClassA every time you make a reference in ClassB routine.
What you can do, if ClassA is some sort of module which stores common functions is just use its as a Shared class and Shared methods, if it is the real problem.

Which Event Handler is called first?

Please see the code below:
Imports ComponentAndControl
Public Class Form1
Delegate Function Compare1(ByVal intNumber1 As Integer, ByVal intNumber2 As Integer) As Boolean
Public Event e()
Public Event e2(ByVal o As Object, e As EventArgs)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim Test As New TestEventArgs
Test.Name = "Bert"
Test.Age = 34
RaiseEvent e2(Me, Test)
End Sub
Public Sub TestHandler4(ByVal o As Object, ByVal e As TestEventArgs) Handles Me.e2
MsgBox(e.Name)
MsgBox(e.Age)
End Sub
Public Sub TestHandler5(ByVal o As Object, ByVal e As TestEventArgs) Handles Me.e2
MsgBox(e.Name)
MsgBox(e.Age)
End Sub
End Class
Public Class TestEventArgs
Inherits EventArgs
Public Name As String
Public Age As Integer
End Class
Which event handler is called first? I.e. TestEventHandler4 or TestEventHandler5? Is it possible to configure this?
Event order when invoking a MultiCastDelegate is undefined in the .Net specification. They are typically invoked in the order they are added, in code order in your case, but don't rely on it.
UPDATE
This MSDN article seems to indicate that the invocation order is now guaranteed to be the order they were added. I haven't actually verified this in practice, and I'm not sure what order Auto wireup events are added.
https://msdn.microsoft.com/en-us/library/system.multicastdelegate(v=vs.110).aspx

inside class calling form1 sub

Hey all i am trying to call a public sub within a class that resides within my form1 code:
Public Class Form1
Public Shared objItem As ListViewItem
Class Server
Private Shared Sub StringMessageReceived(ByVal sender As Object, ByVal e As StringMessageEventArgs)
MsgBox("Received message: " & Convert.ToString(e.Message))
'Form1.ListView1.Items.Add(Convert.ToString(e.Message))
Call Form1.writeToLV(Convert.ToString(e.Message))
End Sub
End Class
Public Sub writeToLV(ByRef theStuff As String)
MsgBox(theStuff)
objItem = ListView1.Items.Add(theStuff)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListView1.View = View.Details
ListView1.Columns.Add("Response", CInt(500))
End Sub
End Class
It sends the value over just fine but when it gets to putting it into the listview it never does?
Any pointers?
David
The most likely explanation is that the form that has been opened on the screen is not the default instance referenced by Form1 in the Server class.
I think that you need to restructure your code somewhat: if you are only going to have one instance of Form1, explicitly create the form and keep a reference to it in a global variable (i.e. g_Form1) rather than relying on the VB-provided default instance (assuming you are ever only going to have 1 instance of the form.
If you can have more than 1 instance of Form1, I would convert your internal Server static class to an Interface and when a new form is created, have it register itself with whatever mechanism is calling Server.StringMessageReceived.

multiple forms in vb.net

can we have a single global variable which can be manipulated by multiple forms
In short, yes. You can have a global variable in a module (.mod) file or a class (.vb) file.
Module Module2
Public variable As String = "Testing"
End Module
Declare a variable like this:
Public Shared myVariable as Type
and access it from any form.
You can access a single variable from any form, if it is declared as public.
If you are defining it in form1 and want to use it in form2, then from inside form2 you can call the variable as - form1.<variable_name>
Take an example-
Form1 code
Public Class Form1
Public a As Integer = 10
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Form2.Show()
End Sub
End Class
Form 2 code
Public Class Form2
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MsgBox(Form1.a)
End Sub
End Class
Yes, it can be done. If you declare it as shared it will exist in only one instance.
Public Class SomeClass
Public Shared SomeField As String
End Class
I would, however, recommend to wrap access to the field into a property:
Public Class SomeClass
Private Shared _someValue As String
Public Shared Property SomeProperty() As String
Get
Return _someValue
End Get
Set(ByVal value As String)
_someValue = value
End Set
End Property
End Class
By wrapping it into a property you will make it easier to troubleshoot problems around the value in case such scenarios would appear in the future.
What you are looking for is the "singleton pattern".
But first, you should ask yourself if you really need it. Maybe this variable could be passe as a parameter to a function or a property.
Use
Public x As Integer
On any Of the Forms and then when you want to use that variable on other form then you can type the form name and then a dot and then the variable name
like this
form1.x
Cheers!!!