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.
Related
Dim dict1 = fileToDict(PriceList)
Dim dict2 = dict1.ToDictionary(Function(y) Val(y))
Basically I am turning dict(of string,string) to dict(of string, double).
My question is I do not see any overload of toDictionary that takes a single function of stuff.
Note: The correct format is actually
Dim dict2 = dict1.ToDictionary(Function(x) x.Key, Function(y) Val(y.Value))
All of the overloaded operator takes 1 function that takes a keyvaluepair as argument.
Somehow the one that works use 2 function. That's where I am confused.
You need to specify a selector for both the keys and the values. There's no overload that is going to simply take the keys from the original Dictionary. Remember that ToDictionary is actually called on an IEnumerable(Of T) so it has no idea that the source is a Dictionary. It only knows that it is an IEnumerable(Of KeyValuePair(Of String, String)). You have to tell it how to get the keys for the new Dictionary from the items in the IEnumerable(Of T) source.
E.g.
Dim dict2 = dict1.ToDictionary(Function(kvp) kvp.Key, Function(kvp) CDbl(kvp.Value))
Dim list As New List(Of String)
list = chkparameter.Items
.Cast(Of ListItem)
.AsEnumerable()
.Where(Function(x) x.Selected)
.Select(Function(x) x.Value)
The error i am getting is
Unable to cast object of type 'WhereSelectEnumerableIterator2[System.Web.UI.WebControls.ListItem,System.String]' to type 'System.Collections.Generic.List1[System.String]'.
How can i rectify it.
Thanks
If you want to assign the result to a List(Of String) variable then you need a List(Of String) object. You can all ToList on any enumerable list to create a List(Of T).
Also, your AsEnumerable call is pointless because Cast(Of T) already returns an IEnumerable(Of T).
Finally, declaring a variable on one line and then setting its value is so unnecessarily verbose. It's not wrong but it is pointless. In your case, not only are you declaring a variable but you're also creating an object that you never use. Don't create a New object if you don;t actually want a new object, which you don;t because you're getting an object on the very next line.
Dim list As List(Of String) = chkparameter.Items.
Cast(Of ListItem).
Where(Function(x) x.Selected).
Select(Function(x) x.Value).
ToList()
There's also no need to declare the type of the variable because it will be inferred from the initialising expression, i.e. ToList returns a List(Of String) so the type of the variable can be inferred from that. Not everyone likes to use type inference where it's not completely obvious though, so I'll let you off that one. I'd tend to do this though:
Dim list = chkparameter.Items.
Cast(Of ListItem).
Where(Function(x) x.Selected).
Select(Function(x) x.Value).
ToList()
By the way, notice how much easier the code is to read with some sensible formatting? If you're going to use chained function syntax like that, it's a very good idea to put each function on a different line once you get more than two or three.
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()
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)
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.