Defining the type of a List in vb.net at runtime - vb.net

I'm creating a class at run time using typebuilder and after I create this class I want to define its type for a list like
dim fooList as new List(of DynamicClassName)
Since this doesn't exist at compile time of course it throws an error. When I generate this type I return the type so I can't do something like
dim newType = createNewType(foobar)
dim fooList as new List(of getType(newType))
How do I assign the type of a List at runtime?

You can create a List(Of T), but AFAIK you won't be able to cast it to a typed object. I've used the String type in the following example.
Dim list As Object = Activator.CreateInstance(GetType(List(Of )).MakeGenericType(New Type() {GetType(String)}))
Debug.WriteLine((TypeOf list Is List(Of String)).ToString())
Output
True
So in your case it would look like this:
Dim newType = createNewType(foobar)
'Creates a List(Of foobar):
Dim list As IList = Ctype(Activator.CreateInstance(GetType(List(Of )).MakeGenericType(New Type() {newType})), IList)
'Creates a BindingList(Of foobar):
Dim bindingList As IBindingList = Ctype(Activator.CreateInstance(GetType(BindingList(Of )).MakeGenericType(New Type() {newType})), IBindingList)

This does not answer your question, but may solve your problem.
Another option would be to use an ArrayList (for which you don't have to assign a type). You can see the details here: http://msdn.microsoft.com/en-us/library/system.collections.arraylist(v=vs.110).aspx.
Here is a basic example:
Dim anyArrayList as new ArrayList()
anyArrayList.add("Hello")
anyArrayList.add("Testing")

Related

vb.net create objects in for each loop from partial info in Ienumerable

Summary:I want to create objects in a for each loop.
I have a class - Dashboard, which has some properties - length, height, etc.
This info is contained within an XML document, but my class' properties is only a small subset of the information in the XML.
I have created a Collection of XElement, and I can iterate over these, but how do I create my object on each iteration of the loop?
Dim Col_DashBoards As IEnumerable(Of XElement) = From XDashboard In XDocument.Load(filename).Descendants("dashboard")
For Each XDashboard In Col_DashBoards
'PseudoCode
Dim Xdashboard.Name as New DashboardClassObject
Xdashboard.Name.Height = XDashboard.Element("Height").value
...
Next
If I have understood your question correctly, you wish to create a new object based on a subset of data from within an XML document?
The below is a function that will generate a new DashboardClassObject for every matching node and populate that object. A list of type DashboardclassObject is returned.
Public Function GenerateDashBoardFromXML(filename as string) As List(Of DashboardClassObject)
Dim dashboardList As List(Of DashboardClassObject) = New List(Of DashboardClassObject)()
Dim Col_DashBoards As IEnumerable(Of XElement) = From XDashboard In XDocument.Load(filename)?.Descendants("dashboard")
For Each XDashboard In Col_DashBoards
Dim dashboard As DashboardClassObject = New DashboardClassObject () With {
.Name = XDashboard.Element("Height")?.value
}
dashboardList.Add(dashboard)
Next
return dashboardList
End Function
It should be noted that Null checking is used here. The below is only populated if the matching element is found. Null coalescing operator is also an option here.
.Name = XDashboard.Element("Height")?.value

Create an object from another objects type

In Visual Basic.net, can I create an Object, or a List of T with the type from another object.
Here is some code:
Dim TestObjectType As Author
Dim TestObject As TestObjectType.GetType
I am getting an error:
TestObjectType.GetType is not defined
EDIT
Can I create a Type object of a certain type, and then create objects, lists or cast objects to this type from this Type object?
Dim TestObject As TestObjectType.GetType will look for a type named GetType in the namespace TestObjectType.
To create an instance of a class using System.Type, you can use Activator.CreateInstance:
Dim TestObject = Activator.CreateInstance(TestObjectType.GetType())
To create a generic list, you can use Type.MakeGenericType:
Dim listType = GetType(List(Of )).MakeGenericType(TestObjectType.GetType())
Dim list = Activator.CreateInstance(listType)
Note that both snippets above return an Object; however, you can make use of generics to achieve compile time safety:
Dim TestObject = CreateNew(TestObjectType)
Dim AuthorList = CreateNewList(TestObjectType)
...
Function CreateNew(Of T As New)(obj As T) As T
Return New T()
End Function
Function CreateNewList(Of T)(obj As T) As List(Of T)
Return New List(Of T)
End Function

.NET: Quick way of using a List(Of String) as the Values for a new Key/Value collection?

I have a List(Of String) object and need to create a new collection based on the strings' values. The new collection will be of a custom class with two string fields - call them Key and Value (but it's not the built-in KeyValue class, it's a custom class).
All the values of Key will be the same, it's just Value that I want to source from the string list. Example:
Dim slValues = New List(Of String)({"Cod", "Halibut", "Herring"})
Dim myList = New List(Of myClass)( ... amazing initialisation line here? )
Class myClass
Public Key As String ' This will always be "Fish"
Public Value As String ' This will be the fish name.
End Class
(Note I don't actually have access to the class I'm using, so can't just change it to Public Key As String = "Fish" as a default. Key must be set at runtime.)
I can of course just do a loop and do it manually, but I'm wondering if there's a whiz-bang way to achieve this as part of the initialisation line?
How about this
Dim myList = slValues.ConvertAll(Of myClass)( _
Function(s) New YourClass With {.Key = "Fish", .Value = s})
Here's an alternative to Jodrell's answer using Linq's Select function:
Dim myList = slValues.Select(Function(fish) New CustomClass With {.Key = "Fish", .Value=fish}).ToList()
from x in Enumerable.Range(1, slValues.count-1).ToArray
select new KeyValuePair(of string,myClass) with {.Key=slValues(x),.Value=myList(x)}
hope it helps.

VB.NET ArrayList to List(Of T) typed copy/conversion

I have a 3rd party method that returns an old-style ArrayList, and I want to convert it into a typed ArrayList(Of MyType).
Dim udc As ArrayList = ThirdPartyClass.GetValues()
Dim udcT AS List(Of MyType) = ??
I have made a simple loop, but there must be a better way:
Dim udcT As New List(Of MyType)
While udc.GetEnumerator.MoveNext
Dim e As MyType = DirectCast(udc.GetEnumerator.Current, MyType)
udcT.Add(e)
End While
Dim StronglyTypedList = OriginalArrayList.Cast(Of MyType)().ToList()
' requires `Imports System.Linq`
Duplicate.
Have a look at this SO-Thread: In .Net, how do you convert an ArrayList to a strongly typed generic list without using a foreach?
In VB.Net with Framework < 3.5:
Dim arrayOfMyType() As MyType = DirectCast(al.ToArray(GetType(MyType)), MyType())
Dim strongTypeList As New List(Of MyType)(arrayOfMyType)
What about this?
Public Class Utility
Public Shared Function ToTypedList(Of C As {ICollection(Of T), New}, T)(ByVal list As ArrayList) As C
Dim typedList As New C
For Each element As T In list
typedList.Add(element)
Next
Return typedList
End Function
End Class
If would work for any Collection object.
I would like to point out something about both the DirectCast and System.Linq.Cast (which are the same thing in the latest .NET at least.) These may not work if the object type in the array is defined by the user class, and is not easily convertable into object types that .NET recognizes. I do not know why this is the case, but it seems to be the problem in the software for which I am developing, and so for these we have been forced to use the inelegant loop solution.

VB.Net - how can i get the type of the object contained in an List

If I have a list...
dim l as List(of MyClass) = new List(of MyClass)
and I want to get the type of the objects contained in the list, how do I do that?
The obvious answer, that doesn't seem to be possible from my actual implementation, would be to do something like this...
public function GetType(byval AList as IList(of GenericType)) as System.Type
dim lResult as system.type = nothing
if AList.Count > 0 then lResult = AList(0).GetType
return lResult
end function
But what if the list is empty and I still want to know the type it contains?
There's a good article on this at MSDN, here
Basically you can use GetGenericArguments() to get an array of the types provided as arguments to your generic type. In the case of a List, there's only one argument so you will get what you need using eg
dim l as List(of MyClass) = new List(of MyClass)
dim t as Type = (l.GetGenericArguments())(0)