Got this code piece from the following Source. Can someone tell me what is the role of the MyBase.New() referred to as statement 2 below. IMHO it does nothing as there is no base/derived classes - only one class is present. For example, when we pass an integer value to the constructor as in Dim iList As New simpleList(Of Integer)(2) the size of the items array in statement 3 is 2 (or 3 elements). Any help pls??
Imports System
Module Program
Sub Main(args As String())
Dim iList As New simpleList(Of Integer)(2)
Console.ReadLine()
End Sub
End Module
Public Class simpleList(Of itemType)
Private items() As itemType
Private top As Integer
Private nextp As Integer
Public Sub New()
Me.New(9) 'Statement 1
End Sub
Public Sub New(ByVal t As Integer)
MyBase.New() 'Statement 2
items = New itemType(t) {} 'Statement 3
top = t
nextp = 0
End Sub
End Class
Related
I'm trying to make a application, in this application I have a List(of T) collection that holds an object.
When processing the object I need to know it's Index from the list.
Example:
Public Class
Public oList as New List(of TestObject)
Private Sub Test()
Dim NewObject As New TestObject
oList.add(NewObject)
Index(NewObject)
End Sub
Private Sub Index(Byval TestObject As TestObject)
debug.print(Testobject.index)
End Sub
End Class
Is something like this possible? Ive seen it available in a reference file I used some time ago, but now I would like to make this available within my own class.
Can someone provide a sample?
PS: I know I can get the index using the List(Of T).IndexOf Method (T) but for future possibilities I would like to make the call from the object itself.
What usually happen is that they have a custom list, they don't directly used List(Of T) and store the list inside the object when they add that item to the list.
Module Module1
Sub Main()
Dim someList As New CustomList
someList.Add(New CustomItem())
someList.Add(New CustomItem())
someList.Add(New CustomItem())
Console.WriteLine(someList(1).Index)
Console.ReadLine()
End Sub
End Module
Class CustomItem
' Friend since we don't want anyone else to see/change it.
Friend IncludedInList As CustomList
Public ReadOnly Property Index
Get
If IncludedInList Is Nothing Then
Return -1
End If
Return IncludedInList.IndexOf(Me)
End Get
End Property
End Class
Class CustomList
Inherits System.Collections.ObjectModel.Collection(Of CustomItem)
Protected Overrides Sub InsertItem(index As Integer, item As CustomItem)
If item.IncludedInList IsNot Nothing Then
Throw New ArgumentException("Item already in a list")
End If
item.IncludedInList = Me
MyBase.InsertItem(index, item)
End Sub
Protected Overrides Sub RemoveItem(index As Integer)
Me(index).IncludedInList = Nothing
MyBase.RemoveItem(index)
End Sub
End Class
It looks like this
Public oList As New List(Of TestObject)
Private Sub Test()
Dim NewObject As New TestObject(oList.Count)
oList.add(NewObject)
End Sub
Public Class TestObject
Public index As Integer
Public Sub New(IndxOfObj As Integer)
Me.index = IndxOfObj
End Sub
End Class
If you necessarily need to have it as a property on the object I would suggest the following:
Public Class Main
Public oList As New List(Of TestObject)
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim NewObject As New TestObject(Me)
oList.Add(NewObject)
Dim NewObject2 As New TestObject(Me)
oList.Add(NewObject2)
MsgBox(NewObject2.Index)
End Sub
Public Function Index(ByVal TestObject As TestObject) As Integer
Return oList.IndexOf(TestObject)
End Function
End Class
Public Class TestObject
Private _main As Main
Public ReadOnly Property Index() As Integer
Get
Return _main.Index(Me)
End Get
End Property
Public Sub New(RootClass As Main)
_main = RootClass
End Sub
End Class
If you happen to have the Main class as a Singleton you can skip the whole sending 'Me' into the constructor business. Then you can just call Main.Index without storing it as a property on all TestObjects.
I have a shared array that needs a calculation for each index. Right now, the array is initialized in New() and executes each time an object is created, which is redundant. How can I set it up so that the array is only initialized once, when it is created? Something like a static block in Java?
I didn't initially include the code because I thought this was just a simple question. The constructor is called 64 times (working with values of bits) and he relevant code is :
' Decimal value of each bit
Public Shared bitValue(63) As Long
Public Sub New()
' Other non-relevant code here.
For index = 0 To 63
bitValue(index) = 1L << index
Next
End Sub
Just in case you are wondering what the heck I'm doing, I'm rewriting a Java program that I did that works with casting and bitwise operators. As part of learning VB, I'm working on a translation. You can get an idea of where it is headed by going to http://sourceforge.net/projects/javabitwise/.
You can initialize it right away
Class Test1
Private Shared _list As New List(Of String) From {"1", "2"}
End Class
Or do it in a shared constructor
Class Test2
Private Shared _list As List(Of String)
Shared Sub New()
_list = New List(Of String)
_list.Add("1")
_list.Add("2")
End Sub
End Class
Or check if the value is initialized or not in the new
Class Test3
Private Shared _list As List(Of String)
Public Sub New()
' Use synclock
If _list Is Nothing Then
_list = New List(Of String)
_list.Add("1")
_list.Add("2")
End If
End Sub
End Class
Or put your list in a singleton
Here's a quick example of the Singleton approach. We access the class via its Instance() function:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print(KibblesAndBits.Instance.bitValue(10))
End Sub
End Class
Public Class KibblesAndBits
Private Shared _Kibbles As KibblesAndBits = Nothing
Public Shared Function Instance() As KibblesAndBits
If IsNothing(_Kibbles) Then
_Kibbles = New KibblesAndBits ' the private constructor will now fire and initialize
End If
Return _Kibbles
End Function
Public bitValue(63) As Long
Private Sub New() ' Private Constructor means you can't instantiate it directly
For index = 0 To bitValue.Length - 1
bitValue(index) = index
Next
End Sub
' ... other standard Class code ...
End Class
So here is my problem. I have a Class of Products and i have created an ArrayList of that class.
I can add lot of new Products to that Array but the problem is that the Array change all the Values of the Array as the last one i have added.
Product Class:
Public Class Product
Dim cod_prod As String
Dim state As Boolean
Public Sub New(ByVal cod As String, ByVal est As Boolean)
cod_prod = cod
state = est
End Sub
Public Sub New()
cod_prod = ""
state = False
End Sub
Public Function get_cod_prod() As String
Return cod_prod
End Function
Public Function get_state() As Boolean
Return state
End Function
Public Sub set_cod_prod(ByVal cod As String)
cod_prod = cod
End Sub
Public Sub set_state(ByVal est As Boolean)
state = est
End Sub
End Class
And this class is were i add a new Product to the ArrayList.
Dim array_prod As New ArrayList
Dim nproducts As Integer = 0
Public Sub add_prod(ByVal prod As Producto)
array_prod.Add(prod)
nproducts += 1
End Sub
Thanks for help.
Ok, looking a bit more on related questions i have found this.
Retrieving data from a VB.NET arraylist of objects
So i solve it changing the method like this:
Public Sub add_prod(ByVal prod As Producto)
Dim nprod As New Producto
nprod.set_cod_prod(prod.get_cod_prod)
nprod.set_state(prod.get_state)
array_prod.Add(nprod)
nproductos += 1
End Sub
I'm new to programming, OOP and Unit Test so please forgive me for my lack of knowledge.
As part of my Rock, Paper and Scissors game I have a abstract superclass (Weapon) which has subclasses (Rock, Paper and Scissors) in VB.NET like:
Public MustInherit Class Weapons
Public MustOverride Function compareTo(ByVal Weapons As Object) As Integer
End Class
Public Class Paper
Inherits Weapons
Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
If TypeOf Weapons Is Paper Then
Return 0
ElseIf TypeOf Weapons Is Rock Then
Return 1
Else
Return -1
End If
End Function
End Class
Public Class Rock
Inherits Weapons
Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
If TypeOf Weapons Is Rock Then
Return 0
ElseIf TypeOf Weapons Is Scissors Then
Return 1
Else
Return -1
End If
End Function
End Class
Public Class Scissors
Inherits Weapons
Public Overrides Function compareTo(ByVal Weapons As Object) As Integer
If TypeOf Weapons Is Scissors Then
Return 0
ElseIf TypeOf Weapons Is Paper Then
Return 1
Else
Return -1
End If
End Function
End Class
Also have a superclass Player which has subclasses (PlayerComputerRandom, PlayerHumanPlayer and PlayerComputerTactical) like:
Imports RockPaperScissors.Weapons
Public Class Player
Private pName As String
Private pNumberOfGamesWon As String
Public pWeapon As Weapons
Property Name() As String
Get
Return pName
End Get
Set(ByVal value As String)
pName = value
End Set
End Property
Property NumberOfGamesWon As String
Get
Return pNumberOfGamesWon
End Get
Set(ByVal value As String)
pNumberOfGamesWon = value
End Set
End Property
Property getWeapon As Weapons
Get
Return pWeapon
End Get
Set(ByVal value As Weapons)
pWeapon = value
End Set
End Property
Public Sub pickWeapon(ByVal WeaponType As String)
If WeaponType = "Rock" Then
pWeapon = New Rock()
ElseIf WeaponType = "Paper" Then
pWeapon = New Paper()
Else
pWeapon = New Scissors()
End If
End Sub
End Class
Imports RockPaperScissors.Weapons
Public Class PlayerComputerRandom
Inherits Player
Private Enum weaponsList
Rock
Paper
Scissors
End Enum
Public Overloads Sub pickWeapon()
Dim randomChoice = New Random()
Dim CompChoice As Integer = randomChoice.Next(0, [Enum].GetValues(GetType(weaponsList)).Length)
If CompChoice = "0" Then
pWeapon = New Rock()
ElseIf CompChoice = "1" Then
pWeapon = New Paper()
Else
pWeapon = New Scissors()
End If
End Sub
End Class
Public Class PlayerComputerTactical
Inherits Player
Private plastMove As String
Property lastMove() As String
Get
Return plastMove
End Get
Set(ByVal value As String)
plastMove = value
End Set
End Property
Public Overloads Sub pickWeapon()
' Add tactical player functionality
End Sub
End Class
Public Class PlayerHumanPlayer
Inherits Player
End Class
I have the GameForm class which instantiates the objects and performs various other logic used for the front-end as shown below:
Public Class GameForm
Private Sub btnRock_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRock.Click
findWinner("HumanPlayer", "Rock", "RandomComputer")
End Sub
Private Sub btnPaper_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPaper.Click
findWinner("HumanPlayer", "Paper", "RandomComputer")
End Sub
Private Sub btnScissors_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnScissors.Click
findWinner("HumanPlayer", "Scissors", "RandomComputer")
End Sub
Public Sub findWinner(ByVal p1name As String, ByVal p1WeaponSelected As String, ByVal p2Name As String)
Dim player1 = New PlayerHumanPlayer()
Dim player2 = New PlayerComputerRandom()
player1.Name = p1name
player1.pickWeapon(p1WeaponSelected) ' Should I be using the Rock Class???
player2.Name = p2Name
player2.pickWeapon()
Dim winner As Integer = player1.getWeapon().compareTo(player2.getWeapon())
Select Case winner
Case 1
txtGameStatus.Text = player1.Name() + " wins!"
Case -1
txtGameStatus.Text = player2.Name() + " wins!"
Case 0
txtGameStatus.Text = "Draw!"
End Select
End Sub
End Class
I need to write unit tests of this using visual studio 2010. As I have never done this, I don't know what unit tests I could include (apart from the stand adding/substract examples). Could someone kindly provide a few unit tests to get started. It will give me a starting point.
Any help would be greatly appreciated.
Manys thanks in advance
My first tip would be to change all of your methods into functions which return a value, this is for the methods you want to unit test. Doing this will ensure that you can use the function for a unit test.
I can give you help for the structure, but I'm afraid I wont be doing your unit tests for you!
Ill show you an example unit test which I have in a solution, it may not be relevant to your solution but the structure is there nevertheless. First off I have the function (add) which i would like to test, and in a unit test project i have the test.
Function to test
Public Function Add(value1 As Int32, value2 As Int32)
answer = value1 + value2
Return answer
End Function
This is the unit test I am using within my unit test class
<TestMethod()> _
Public Sub AddTest()
Dim target As Form1 = New Form1()
Dim value1 As Int32 = 10
Dim value2 As Int32 = 35
Dim actual As Int32 = 45
Dim result As Int32 = target.Add(value1, value2)
Assert.AreEqual(result, actual)
End Sub
To try to give you an example of how you might structure this:
First of all, instead of this:
Public Overloads Sub pickWeapon()
' Logic...
End Sub
You might want to do something like this:
Public Overloads Function pickWeapon() as Weapons
Dim selectedWeapon as Weapons = Nothing;
// logic to set weapon here
return selectedWeapon;
End Sub
Now you can call that from a UnitTest, and make sure it returns an object which is a valid Weapon, for instance (not necessarily the most useful test, but hopefully, you get the point! :) ).
If your restructure the method findWinner() in a similar way, you can test that the logic of that method finds the correct winner.
Note however, that you should separate the logic for finding a winner from the weapon-picking. That is, you should create the players outside of that method, and pass them in to findWinner(). This will let you pass in certain options (weapons), and check that you get the expected result. You can't do that at the moment, since the weapon "player2" will use is selected by random inside findWinner().
Start by changing it so it will have a signature similar to the following:
' Takes two players in, and returns the name of the winner
Public Sub findWinner(ByVal humanPlayer As PlayerHumanPlayer,
ByVal computerPlayer As PlayerComputerRandom) As String
A (very simple) test, assuming you've rewritten the code to fit this:
<TestMethod()> _
Public Sub ShouldReturnPlayer1AsWinner()
Dim player1 = New PlayerHumanPlayer("Human name", New Scissors())
Dim player2 = New PlayerComputerRandom("Computer", New Rock())
Dim result As String = findWinner(player1, player2)
Assert.AreEqual(result, "Computer")
End Sub
Again, this may not be the be the best test, but it should give you an idea, and help you get started.
Sidenote: I would call the super-class Weapon, not Weapons. Think of it this way: You can have many many different instances of it, and they can be different weapons (paper, scissor, etc), but each is still a single weapon.
I have a simple class List.vb which is the following:
Public Class List
Public fList As List(Of Integer)
Public Sub New()
fList = New List(Of Integer)
fList.Add(1)
fList.Add(2)
fList.Add(3)
fList.Add(4)
fList.Add(5)
End Sub
End Class
The Console application is using this class like the following:
Module Module1
Sub Main()
Dim fObject As List = New List
Dim cnt As Integer = 0
For Each x As Integer In fObject.fList
Console.WriteLine("hello; {0}", fObject.fList.Item(cnt).ToString())
cnt = cnt + 1
Next
Console.WriteLine("press [enter] to exit")
Console.Read()
End Sub
End Module
Can I change the class code so that List.vb is a list(of integer) type?
This would mean that in the Console code I could replace In fObject.fList with just In fObject?
Or am I barking up the wrong tree - should classes be single objects and lists should be collections of classes ?
Yes, you can do that. In order for an object to be compatible with For Each, it must have a GetEnumerator function:
Public Function GetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return New IntListEnum(fList)
End Function
The IntListEnum class must, in turn, implement IEnumerator, like this:
Public Class IntListEnum Implements IEnumerator
Private listInt As List(Of Integer)
Dim position As Integer = -1
Public Sub New(ByVal fList As List(Of Integer))
listInt = fList
End Sub
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
position = position + 1
Return (position < listInt.Count)
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
Public ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Try
Return listInt(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
End Class
Now you can make fList private, and iterate your List as follows:
For Each x As Integer In fObject
You can see a complete example here.
The answer that dasblinkenlight has provided is excellent, but if all you need is a list that of integers that is pre-populated, you can just inherit from List(Of Integer) and then have the class populate itself in the constructor:
Public Class List
Inherits List(Of Integer)
Public Sub New()
Add(1)
Add(2)
Add(3)
Add(4)
Add(5)
End Sub
End Class
When you inherit from List(Of Integer), your class automatically gets all of the functionality implemented by that type, so your class also becomes a list class that works the same way. Then, you can just use it like this:
Dim fObject As New List()
For Each x As Integer In fObject
Console.WriteLine("hello; {0}", x)
Next