Module Module1
Class Arithmetical
Public Function Subtract(ByVal a As Integer, ByVal b As Integer)
Return a - b
End Function
End Class
Sub Main()
Dim objArithmetical As New Arithmetical()
Console.WriteLine(objArithmetical.Subtract(80, 27))
Console.ReadKey()
End Sub
End Module
How would I implement a constructor into this? I am new to this coding and language(VB.NET) Anything would be greatly appreciated.
Thank You
If you need to implement a constructor, you can use the code below :
Public Sub New()
End Sub
For more info, you can find some documentation here : MSDN or DotNetPerls
Hope it helps !
Related
I want to call Dim objFkkiNinteiJokyoRpt As New A(objCsv) in class C. But class A Inherits Common. If now call contructor will An error occurred.Because type Object C.CsvGenerator diference type Object in common. I thnk now stop call to contructor common (or any other way) but i dont know how to do. Helf me please. Sorry because my english so bad
Public Class A Inherits Common
Public _objCsv As C.CsvGenerator
Friend Sub New(ByVal objCsv As C.CsvGenerator)
_objCsv = objCsvGenerator
End Sub
Public Sub New()
End Sub
End Sub
Public Sub New(ByVal objRSReportObj As Object)
MyBase.New(objRSReportObj)
InitializeReport()
End Sub
End Class
Public Class C
Private Function SelectCSV
Dim objCsv As New CsvGenerator("")
Dim objFkkiNinteiJokyoRpt As New A(objCsv)
End Function
Friend Class CsvGenerator
Inherits cmShare.cmObject
End Class
End Class
Public Class Common
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal objRSReport As Object)
MyBase.New(objRSReport)
End Sub
End Class
I am newbie here. I need your help. I am trying to develop a tool where I want to implement multi-threading in vb.net. I am stuck in a place which I could not resolve. Let me explain you.
I have created a custom class as below:
Public Class TestClass
'Few private Members of my class
Private a As String,b As String
Public Structure abc
Dim xx as object
Dim yy as object
Dim zz as object
End Structure
Public aa(10) As abc
'Now I needed to override the constructor as the initialization of
'instance of this class can be made in two different ways due to
'requirement
Public Sub New(ByVal xy As String,ByRef yz As Object)
'Some internal method to initialize the object
Me.a=xy
Me.b=xy
End Sub
'Another way to create the instance
Public Sub New(ByVal xy As String,ByVal yz As String)
'Some internal method to initialize the object
Me.a=xy
Me.b=yz
End Sub
'Now a public method which I want to call using threading
Public Sub TestSub()
'Do something with Me.a,Me.b and aa(some index)
End Sub
End Class
Now in a different module I am creating the instance of this class as below:
Dim X1 As New TestClass("Some String",<Some Object reference>)
Dim X2 As New TestClass("Some String","Some String")
Now I have declared a sub in the same module like below
Sub DoMyStuff(ByRef A1 As TestClass)
A1.TestSub()
End Sub
After all This I want to create a thread and run the sub "DoMyStuff" by Passing a reference of X1
To Do this I have Imported System Threading:
Imports System.Threading
Inside Module after initialization of X1 and X2 I have written:
Dim T1 as New Threading.Thread(AddressOf DoMyStuff)
T1.Start(X1)
Here I am getting error: Overload Resolution Failed because no 'New' can be called with this arguments: 'Public Sub New(Start As System.Threading.ParameterizedThreadStart, maxStackSize As Integer)': Method 'Public Sub DoMyStuff(ByRef A1 As TestClass)' does not have a signature compatible with delegate 'Delegate Sub ParameterizedThreadStart(obj As Object)'. 'Public Sub New(Start As System.Threading.ThreadStart, maxStackSize As Integer)': Method 'Public Sub DoMyStuff(ByRef A1 As TestClass)' does not have a signature compatible with delegate 'Delegate Sub ThreadStart()'.
If I am writing like this,
Dim T1 As Threading.Thread
T1 = (AddressOf DoMyStuff)
T1.Start(X1)
I am getting the error: 'AddressOf' expression can not be converted to 'System.Threading.Thread' because 'System.Threading.Thread' is not a delegate type.
Might be I am missing some thing, which I am unable to find. I am not so much good in Delegate type concept. Also this is my first project with implementation of Threading. Looked for answers in Google but unable to understand to sort out. Your help highly solicited.
Thanks
Edit:
I have checked your reference Michael Z. and its really helpful. First of all a big Thank you for that :)
However, I am unable to understand a thing in there. If you help me out there, I would be highly grateful. As per my understanding, I have changed my code as below:
Public Delegate Sub Test2(ByRef A1 as TestClass)
Public T1 as Test2 = New Test2(AddressOf DoMyStuff)
Public Sub DoMyStuff(ByRef A1 as TestClass)
A1.TestSub()
End Sub
Now I have Declared in my module as follows:
Dim T as Threading.Thread = New Threading.Thread(AddressOf DoStuff)
Here I am unable to understand how to write the DoStuff sub as in your example you were working with TextBox1 which is an object in UI, so you wrote:
Public Sub DoStuff()
If TextBox1.InvokeRequired Then
TextBox1.Invoke(T1,"Hello")
End If
End Sub
But here I need to work with an object which is custom made i.e. X1 or X2. Also I need to pass the reference of the object in the Thread so that the method TestSub can work with the created object either X1 or X2. Totally lost here :(
Please correct me if anywhere I am wrong to understand your reference, otherwise if correctly understood, can you Please help me out here. Appreciate your help in advance.
Thanks
Firstly, ensure you're calling this from a method:
Dim T1 as New Threading.Thread(AddressOf DoMyStuff)
T1.Start(X1)
Next remove the ByRef in the method parameter like so Sub DoMyStuff(A1 As TestClass)
Essentially make your second Module look like:
Module Module2
Dim X1 As New TestClass("Some String", "asd")
Dim X2 As New TestClass("Some String", "Some String")
Sub TestCall
Dim T1 as New Thread(AddressOf DoMyStuff)
T1.Start(X1)
End Sub
Private Sub DoMyStuff(A1 As TestClass)
A1.TestSub()
End Sub
End Module
And you can call it like so:
TestCall()
Try using a simple Call method;
Call New Threading.Thread(AddressOf DoMyStuff).Start(X1)
Looking at what you wanting, there seems no reason to assign this to a variable?
Also - remember, when working with multiple contructors, you need to ensure the [TYPES] you pass in are correct and expected (this could be why your current process isn't working).
See this link for a similar issue.
Assuming an object with the following code...
Public Sub New()
Me.Name = "Default Name"
Initialize()
End Sub
Public Sub New(CustomName as String)
Me.Name = CustomName
Initialize()
End Sub
Private Sub Initialize()
'Initialize some other properties
End Sub
Is there a more elegant pattern for this use case? Some way where one constructor could call the other constructor and eliminate the need for the Initialize() method?
Yes, you could write one constructor with all the needed parameters and then write the rest with a call to Me.Constructor() without anything else in the method block that supplies the defaults.
Public Sub New(CustomName as String)
Me.Name = CustomName
End Sub
Public Sub New()
Me.New("Default Name")
End Sub
I'm not sure if there's a VB syntax for constructor chaining in the C# sense, but if I remember correctly VB can invoke other constructors internally by calling Me.New(). Which is kind of the same thing. So you should be able to do something like this:
Public Sub New()
Me.New("Default Name")
End Sub
Public Sub New(CustomName as String)
Me.Name = CustomName
'Initialize some other properties
End Sub
I have this code in my Parser and I want to pass text to Form1 so I can update some Labels or whatever.
(My structure is as follows: Form1 -> Engine -> Parser)
Sometimes I need to pass 2 strings, sometimes more.
Public Class Parser
Public Event NewInfo(<[ParamArray]()> Byval strArray() as String)
Public Sub SomeParser(ByVal m As Match)
Dim strArray() As String = {"Word1", "Word2"}
RaiseEvent NewInfo(strArray)
End Sub
End Class
Then I have this another class. I pass the Array to Engine and after that, to Form1, finally:
Public Class Engine
Private parent as Form1
Private WithEvents Parser As New Parser
Private Sub New(ByRef parent as Form1)
Me.parent = parent
EndSub
Private Sub ChangeLabel(ByVal str() As String) Handles Parser.NewInfo
parent.UpdateTextLabel(str)
End Sub
And then I have this in Form1:
Public Class Form1
Private WithEvents Engine as New Engine(Me)
Public Delegate Sub UpdateTextLabelDelegate(<[ParamArray]()> ByVal text() As String)
Public Sub UpdateTextLabel(ByVal ParamArray str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), str())
Else
(Do stuff here)
End Sub
End Class
The code stops at Me.invoke(New UpdateTextLabelDelegate).... -line.
Exception is something like: System.Reflection.TargetParameterCountException
So it means something like wrong amount of parameters.. How to do this properly?
I would be very pleased if someone could explain and if I could understand how to do this.
I don't think you need <[ParamArray]()> in your code since it's already an array that you are passing:
Public Delegate Sub UpdateTextLabelDelegate(ByVal text() As String)
And as far as passing the data through the invoke, don't use str(), just str
Public Sub UpdateTextLabel(ByVal str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), str)
Else
'(Do stuff here)
End If
End Sub
Finally managed to solve this problem. It wasn't that difficult but my mistake was something inside my own head.
I made no changes to Parser.vb so the above code is Ok.
Also, no changes to Engine.vb.
Changes to Form1.vb are here:
Public Class Form1
Private WithEvents Engine as New Engine(Me)
Public Delegate Sub UpdateTextLabelDelegate(<[ParamArray]()> ByVal text() As String)
Public Sub UpdateTextLabel(ByVal str() As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateTextLabelDelegate(AddressOf UpdateTextLabel), New Object() {str})
Else
'(Do stuff here)
End Sub
End Class
So, all I did was to insert New Object() {args} to the invoke line and removed ParamArray from the Public Sub UpdateTextLabel -line..
But thanks for Kicking my head so I had the reason to go forward! :)
I find myself calling functions from lambdas frequently as the provided delegate does not match or does not have sufficient parameters. It is irritating that I cannot do lambda on subroutines. Each time I want to do this I have to wrap my subroutine in a function which returns nothing. Not pretty, but it works.
Is there another way of doing this that makes this smoother/prettier?
I have read that this whole lambda inadequacy will probably be fixed in VS2010/VB10 so my question is more out of curiosity.
A simple Example:
Public Class ProcessingClass
Public Delegate Sub ProcessData(ByVal index As Integer)
Public Function ProcessList(ByVal processData As ProcessData)
' for each in some list processData(index) or whatever'
End Function
End Class
Public Class Main
Private Sub ProcessingSub(ByVal index As Integer, _
ByRef result As Integer)
' (...) My custom processing '
End Sub
Private Function ProcessingFunction(ByVal index As Integer, _
ByRef result As Integer) As Object
ProcessingSub(index, result)
Return Nothing
End Function
Public Sub Main()
Dim processingClass As New ProcessingClass
Dim result As Integer
' The following throws a compiler error as '
' ProcessingSub does not produce a value'
processingClass.ProcessList( _
Function(index As Integer) ProcessingSub(index, result))
' The following is the workaround that'
' I find myself using too frequently.'
processingClass.ProcessList( _
Function(index As Integer) ProcessingFunction(index, result))
End Sub
End Class
If you find that you are doing it too often and generally with the same type of data, you can wrap the delegate in a class.
Create a base class that converts to the delegate:
Public MustInherit Class ProcessDataBase
Public Shared Widening Operator CType(operand As ProcessDataBase) as ProcessingClass.ProcessData
Return AddressOf operand.Process
End Sub
Protected MustOverride Sub Process(index As Integer)
End Class
Inherit from the class:
Public Class ProcessResult
Inherits ProcessDataBase
Public Result As Integer
Protected Overrides Sub Process(index as Integer)
' Your processing, result is modified.
End SUb
End Class
Use it:
Public Class Main()
Public Sub Main()
Dim processingClass As New ProcessingClass
Dim processor As New ProcessResult
processingClass.ProcessList(processor)
Dim result as integer=processor.Result
End Sub
End Class
It IS fixed in VB10, the VS10 Beta is available, if it's an option for you to use it. In VB10 you have lambdas without a return value, and inline subs/functions.
For now, maybe you could just forget lambdas and work with delegates instead? Something like:
processingClass.ProcessList(AddressOf ProcessingSub)