In C# it's possible to cast to List<T> - so if you have:
List<Activity> _Activities;
List<T> _list;
The following will work:
_list = _Activities as List<T>;
but the translated line with VB.NET which is:
_list = TryCast(_Activities, List(Of T))
throws a compilation error. So I've had a good hunt around and experimented with LINQ to find a way round this to no avail. Any ideas anyone?
Thanks
Crispin
I repro, this should technically be possible. Clearly the compiler doesn't agree. The workaround is simple though:
Dim _Activities As New List(Of Activity)
Dim o As Object = _Activities
Dim tlist = TryCast(o, List(Of T))
Or as a one-liner:
Dim tlist = TryCast(CObj(_Activities), List(Of T))
The JIT compiler should optimize the temporary away so it doesn't cost anything.
You can use the generic List.ConvertAll method.
Given a List the method will return a List of a different type using a converter function you supply.
The MSDN article I linked has an excellent example.
I always use DirectCast(object, type)
Related
I don't understand how to use
Dim List As New ArrayList
Dim Strings() As String
List.Add("hello")
'The following line should simply return an array of strings:
Strings = List.ToArray(Of String) '(syntax error)
Could only find C# examples and didn't figured it out.
Thank you very much!
As suggested, you should be using a List(Of String) in the firtst place if at all possible. It's then simply:
myList.ToArray()
to get a String array. If you're stuck with the ArrayList though, the correct option is:
myList.Cast(Of String)().ToArray()
The Cast method takes in an IEnumerable and outputs an IEnumerable(Of T). The latter is what's required by most extension methods commonly called from the Enumerable class, of which ToArray is an example.
In silverlight my custom controls are in theUIElementCollection of my StackPanel. I want to get a list of them by a specific value. There only DivElements in the container. It returns Nothing when I know I have one or more. I know I can make a simple loop and cast types inline, but I want to get better with LINQ and Cast(Of TResult). My attempt at casting:
Dim myList = TryCast(spDivs.Children.Where(Function(o) DirectCast(o, DivElement).ElementParent Is bComm).Cast(Of DivElement)(), List(Of DivElement))
The problem is you can't cast into a List(Of DivElement). The collection is a UIElementCollection, not a List(Of T).
You could build a new list, though. This can also be simplified by using OfType instead of casting manually:
Dim myList = spDivs.Children.OfType(Of DivElement)()
.Where(Function(o) o.ElementParent Is bComm)
.ToList()
Suppose I have a list of Cat.
Public Class Cat
Public Property id As Guid
Public Property name As String
Public Property race As catRace
End Class
How can I quickly transform this List(Of Cat) into a List(Of Guid) using the id property?
I could do :
Dim newList As List(Of Guid)
For each item in catList
newList.Add(item.id)
Next
But I think there must be a way to do this faster (1 LOC). I just can't find how.
One line of code may make it faster to type, but it won't necessarily be faster to execute.
Dim newList = From c In catList Select c.id
One line of code, using extension methods rather than LINQ.
newList = catList.Select(Function(t) t.id).ToList
If you prefer LINQ
newList = (From c In catList Select c.id).ToList
LINQ. catList.Select(t=>t.id). Not entirely sure what VB equivalent of => is for the lambda though.
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.
i have problem LINQ query.In above,i got error system.object cant be converted to Sytem.String. What can be the problem?
if i use string() instead of ArrayList, it doesn't raise error. But in String(), i should add items manually
Public Shared Function GetCompletionList(ByVal prefixText As String, ByVal count As Integer, ByVal contextKey As String) As String()
Dim movies As New ArrayList()
Dim dt As DataTable = StaticData.Get_Data(StaticData.Tables.LU_TAG)
For Each row As DataRow In dt.Rows
movies.Add(row.Item("DS_TAG"))
Next
Return (From m In movies _
Where m.StartsWith(prefixText, StringComparison.CurrentCultureIgnoreCase) _
Select m).Take(count).ToArray()
End Function
As a general rule, do not ever use ArrayList or any of the other types in System.Collections. These types are deprecated in favour of their generic equivalents (if available) in the namespace System.Collections.Generic. The equivalent of ArrayList happens to be List(Of T).
Secondly, returning an array from a method is generally considered bad practice – although even methods from the framework do this (but this is now widely considered a mistake). Instead, return either IEnumerable(Of T) or IList(Of T), that is: use an interface instead of a concrete type.
You can use List(Of String) instead of ArrayList.
Add a reference to System.Data.DataSetExtensions and do:
return dt
.AsEnumerable() // sic!
.Select(r => r.Item("DS_TAG")) // DataTable becomes IEnumrable<DataRow>
.Where(m => m.StartsWith(prefixText, StringComparison.CurrentCultureIgnoreCase))
.ToArray();
(sorry but that's C# syntax, rewrite to VB.NET as you need)