Dynamically create more than one instance of class and reference it - oop

I want to dynamically create more than one instance of the BindingSource class to be public throughout my Form.
If I use Dim o As Object = Activator.CreateInstance(GetType(BindingSource)) it will only create one instance of this class.
How can I create multiple instances of this class and reference them uniquely.
The number of instances needed is not known at design time, so I cannot do
Dim o1 As Object = Activator.CreateInstance(GetType(BindingSource))
Dim o2 As Object = Activator.CreateInstance(GetType(BindingSource))
Dim o3 As Object = Activator.CreateInstance(GetType(BindingSource))
It's in vb.net
I hope I make sense...
Regards
Marius

Your design doesn't make any sense. But, I'll answer your question, and you can ask a new question to puzzle out the flaws in your design.
Make a dynamic collection, such as List<BindingSource> that you can add to as needed.
Then, in a loop, you can instantiate as many BindingSource as you need, and add them to the List<BindingSource> as needed.

Related

A null reference could result in runtime

Dim policy_key() As RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
Getting error at Line2.
An Error occured - Object reference not set to an instance of an object.
Each element of object arrays also needs to be declared as a new object too.
Dim policy_key() As RenewalClaim.PolicyKeyType
Redim policy_key(0)
policy_Key(0) = new RenewalClaim.PolicyKeyType
policy_key(0).policyEffectiveDt = date_format_string(ld_EffectiveDate)
QUICK TIP: When declaring classes structures etc, it is useful to name them so you can see what type they are....
e.g.
cls_Policy_Key for a class
str_Policy_Key for a structure etc.
When you come back to your code after a year.. you will thank yourself for doing so.
Dim policy_key() As RenewalClaim.PolicyKeyType
is part of your problem. When you are declaring policy_key() you are actually declaring it as an array with no elements. If you don't particularly need to use an array, for example, if you don't need to add objects to a particular element number, you might be better using a list and declaring it like this
Dim policy_key As New List(Of RenewalClaim.PolicyKeyType)
This way, you can add items easily without having to resize your array each time - The code is a little longer than Trevor's answer, but less prone to errors when you extend your code -
dim newPolicy_Key as RenewalClaim.PolicyKeyType
newPolicy_Key.policyEffectiveDt = date_format_string(ld_EffectiveDate)
policy_Key.add(newPolicyKey)

Remove reference from List Of Objects in vb.net

I want to copy the content of one List(Of Object) to another and modify a single value. Is there a way to remove the reference?
In the code sample I get the output 'test2 test2' when I expect 'test1 test2'.
Module Module1
Sub Main()
Dim ListOfSample As New List(Of sample)
Dim var1 As New sample
var1.Name = "test"
ListOfSample.Add(var1)
ListOfSample.Add(var1)
Dim NewListOfSample As New List(Of sample)
NewListOfSample.AddRange(ListOfSample)
NewListOfSample(1).Name = "test2"
Console.Write(NewListOfSample(0).Name & " " & NewListOfSample(1).Name)
End Sub
End Module
Public Class sample
Public Name As String
End Class
Since your list is a list of Objects, when you perform add range, you are not adding "copies", instead you are adding the pointers (references) to the same objects that are in your original list.
You will need to clone all of your objects in the first list, and then add those clones to your second list. When it comes to cloning there are several different ways in .NET. Here's a post on getting deep copies of objects that does a good job explaining your options: Deep Copy of an Object
You can either create a clone method on your "sample" object to return a newly initialized copy of itself, or you can use some of the serialization methods mentioned in the post I linked to.
In the line NewListOfSample.AddRange(ListOfSample) you're adding references to your new list. So whatever you change in your new list will update the reference in your original list (they're both pointing to the same objects). You need to add new instances of Sample to the second list for it to contain independent items.

Dynamic creation of class instances

Is there any way to create class instances on the fly and refer to them later? I have a class with various methods and properties designed to hold & calculate product data. I'd like the application to be able to handle as many individual products as the user needs. This code clearly won't work but it should give you an idea of what I'm asking:
For x = 1 To howEverMany
Dim product_ & x.ToString() As New myProductClass
Next x
I appreciate this may not be the best approach (I should probably use lists or arrays to hold the product data) but I'm curious as to whether this is possible from a technical standpoint. I'm using VB.Net but answers in any .Net language will be welcome. Thanks.
Store them in a List(Of T). Then you can LINQ one or more objects in the list.
'class level
Private Products As New List(Of myProductClass)
'place where you load them
For x As Integer = 1 To howEverMany
Dim myc As New myProductClass
mpc.Id = x
'set other properties as needed
Products.Add(mpc)
Next
Get one by it's Id:
Dim mpc4 = (From p In Products Where p.Id = 4).FirstOrDefault
If Not mpc4 Is Nothing Then
'object exists
End If
You can make other similar queries on your List as well.

VB.Net Running Threading with Reflected Objects

Running into problems creating objects through reflection and then running them on multiple threads.
I just cannot seem to figure out what I need to here:
For Each WorkerNode As XmlNode In oRunSettings.GetWorkerValues
Dim sWorkerName = WorkerNode.Attributes(SETTING_NAME_ID).Value
Dim oWorkerType As Type = Type.GetType(String.Format("Worker.{0}", sWorkerName))
Dim oWorker As Object = Activator.CreateInstance(oWorkerType)
Dim tWorker As Thread = New Thread(AddressOf oWorker.Process)
tWorker.Start()
Next
It is causing errors at the "AddressOf" because Object does not have a method called that. Do I need to do something with an interface?
First of all I want to say that I've never wrote code in VB so I can be completely wrong here but I'll try anyway.
It seems that you hold the created instance as Object instead of it's correct type.
Object does not contain method named Process, hence the error.
try casting the object to the correct type.
I hate when people answer their own question, but while waiting for an answer, I realized that I could just cast the object as its base object, and set the reflection from there. That is working now.

Adding items to list results in duplicates. What is a better way?

I have this code to return a list of fund sources for our organization.
Dim FundSourceList As New List(Of FundSource)
Dim fs As New FundSource
If results.Count > 0 Then
For Each result In results
fs.FundID = result.Item("strFundID")
fs.FundDescription = result.Item("txtFundIDDescr")
fs.ShortFundDescription = result.Item("txtFundIDDescrShort")
FundSourceList.Add(fs)
Next
End If
Return FundSourceList
The problem is that when I loop through the resulting FundSourceList all it shows is the last value. For example, if I have three fund sources (state, federal, athletic), then when I use this code to loop through all I get listed is athletic, athletic, athletic.
For Each FundSource In FundSources
Debug.Print(FundSource.FundDescription)
Next
So I change the code to this. I moved the creation of the fs variable inside the loop.
Dim results = From result In dsResult.Tables(0) Select result
Dim FundSourceList As New List(Of FundSource)
If results.Count > 0 Then
For Each result In results
Dim fs As New FundSource
fs.FundID = result.Item("strFundID")
fs.FundDescription = result.Item("txtFundIDDescr")
fs.ShortFundDescription = result.Item("txtFundIDDescrShort")
FundSourceList.Add(fs)
Next
End If
Return FundSourceList
This works fine but now I'm creating a new class over and over again. It seems a little inefficient to me. Can I not create the class outside the loop and use it over and over again? Thanks.
If you have 3 fund sources, you need three FundSource objects. It's as simple as that. I don't know what's inefficient about it...
How can you add 3 fund sources to your list but just create one?
You're not actually creating a class - the class is the code definition for the methods and properties. When you use the New operation, you're creating an instance of that class, which results in an object. When you have a list of objects, like FundSourceList, you want the items in it to be individual objects. So yes, the solution you have at the bottom is correct. You mention efficiency concerns - when you instantiate the object, basically all that is happening (in this case) is some memory is being allocated to store the variables (and some references for the managed memory, but you don't need to worry about that here). This is necessary and is optimized under-the-hood, so you shouldn't need to worry about that either.
You can't instantiate the object outside of the loop to achieve the result you're after.
This is because your object would be a reference type.
By instantiating outside of the loop, you would create one reference to your object.
When iterating through your results and setting the properties, you'll be using that same reference over and over.
All you're adding to the list on each iteration is the same reference, which by the end of the loop, will refer to an object containing the last values in your result set.
By creating new objects inside the loop, you create new references - each pointing to a new FundSource. Your loop now writes into a fresh object, and get your desired results.