-
Dec 18th, 2020, 02:07 PM
#1
Thread Starter
New Member
Unable to cast object of type <object> to type IEnumerable
Hi folks,
I am buidling this app where I use deserialization to obtain a List of the object "Contact", so far so good. When I try to retrieve the first element from this obtained list (which I sorted and declared in "objsortedData" I get this InvalidCastException:
{System.InvalidCastException: Unable to cast object of type 'Contact' to type 'System.Collections.IEnumerable'. at AdresboekApp.MainPage..ctor()}
See my code below, is it necessary to cast to IEnumerable? And if so, how do I correctly cast my list(values) so that I can use indexation to declare the "firstPerson" variable?
Main Sub:
Code:
Public Sub New()
InitializeComponent()
SupportedOrientations = SupportedPageOrientation.Portrait Or SupportedPageOrientation.Landscape
'Save default persondata to Contacten.xml file on local device
Dim xmlWriterSettings As XmlWriterSettings = New XmlWriterSettings()
xmlWriterSettings.Indent = True
Dim local As System.IO.IsolatedStorage.IsolatedStorageFile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication()
If Not local.DirectoryExists("\Assets") Then local.CreateDirectory("\Assets")
Using stream As IsolatedStorageFileStream = local.OpenFile("\Assets\Contacten.xml", FileMode.Create)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Contact)))
Using xmlWriter As XmlWriter = xmlWriter.Create(stream, xmlWriterSettings)
serializer.Serialize(xmlWriter, GeneratePersonData())
End Using
End Using
'Show first contact in Contacten.xml file on local device
Using stream As IsolatedStorageFileStream = local.OpenFile("\Assets\Contacten.xml", FileMode.Open)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(List(Of Contact)))
Dim persondata As List(Of Contact) = CType(serializer.Deserialize(stream), List(Of Contact))
Dim objsortedData = persondata.OrderBy(Function(t) CStr(t.Firstname))
Dim firstPerson = objsortedData(0)
Me.listBox.ItemsSource = firstPerson
End Using
End Sub
Function GeneratePersonData wich generates a default list of Contact
Code:
'Generate default persondata
Private Function GeneratePersonData() As List(Of Contact)
Dim persondata As List(Of Contact) = New List(Of Contact)()
persondata.Add(New Contact() With {
.Firstname = "Louis",
.Lastname = "van Gaal",
.Emailadress = "louisvangaal@prive.nl"
})
persondata.Add(New Contact() With {
.Firstname = "Patrick",
.Lastname = "Kluivert",
.Emailadress = "patrickkluivert@prive.nl"
})
persondata.Add(New Contact() With {
.Firstname = "Robin",
.Lastname = "van Persie",
.Emailadress = "robinvanpersie@prive.nl"
})
persondata.Add(New Contact() With {
.Firstname = "Arjen",
.Lastname = "Robben",
.Emailadress = "arjenrobben@prive.nl"
})
Return persondata
End Function
Class Contact:
Code:
' Storage of class Contact data
Private _firstname As String
Private _lastname As String
Private _email As String
Public Property Firstname() As String
Get
Return _firstname
End Get
Set(ByVal value As String)
_firstname = value
End Set
End Property
Public Property Lastname() As String
Get
Return _lastname
End Get
Set(ByVal value As String)
_lastname = value
End Set
End Property
Public Property Emailadress() As String
Get
Return _email
End Get
Set(ByVal value As String)
_email = value
End Set
End Property
End Class
End Class
-
Dec 18th, 2020, 09:55 PM
#2
Re: Unable to cast object of type <object> to type IEnumerable
For future reference, please point out exactly where the exception is thrown. We shouldn't have to scan all the code and work it out for ourselves. Presumably the issue is here:
vb.net Code:
Me.listBox.ItemsSource = firstPerson
firstPerson is a single Contact object. If you had read the documentation for that ItemsSource property, which you could have done by clicking it in code and pressing the F1 key, then you'd know that its type is IEnumerable. The whole point is that it is a list of items to display in the control. If you only want to display a single item in the control for some reason then you need to put that into an enumerable list of some sort for the control to read it, e.g. an array. Are you sure that you only want to display the first item though? That seems an odd choice but I don't know anything about your app.
Also, the fact that this made it through to run time rather than being caught at compile time suggests that you have Option Strict Off in your project. You should turn that On in the project properties and also in the IDE options, so it is On by default for future projects. That will enforce strict typing and force you to put more thought into your data types. It will also catch some obvious mistakes like this before running the code.
Last edited by jmcilhinney; Dec 21st, 2020 at 01:08 PM.
-
Dec 21st, 2020, 12:13 PM
#3
Thread Starter
New Member
Re: Unable to cast object of type <object> to type IEnumerable
Hi jmcilhinney,
Thanks for your help.
I need to build this app as a schoolproject, I need to be able to browse trough the contacts in the list, and the first item of Contact has to be shown at startup.
So ItemSource is able to hold the single Contact object right now (whish is the complete List), but if I need to obtain selected items from this List (Contact), I need to split this list into a list of IEnumerrable (of Contact) elements or an Array right?
Assuming this is correct XMLSerializer isnt the best tool to obtain this result, should I use LINQ instead?
-
Dec 21st, 2020, 01:13 PM
#4
Re: Unable to cast object of type <object> to type IEnumerable
If you have a list and you want the first item but you need it as a list, call Take(1) instead of First.
-
Dec 23rd, 2020, 08:13 AM
#5
Thread Starter
New Member
Re: Unable to cast object of type <object> to type IEnumerable
Hi jmcilhinney
I came so far to make the objects "ready" to use XMLDeserialization to read the XML file.
The program runs correctly, but the Array returns an empty list in runtime:
Class Contact
Code:
Public Class Contact
'Storage of class Contact data
Private _Firstname As String
Private _Lastname As String
Private _Email As String
<XmlAttribute("Voornaam")>
Public Property Firstname() As String
Get
Return _Firstname
End Get
Set(ByVal value As String)
_Firstname = value
End Set
End Property
<XmlAttribute("Achternaam")>
Public Property Lastname() As String
Get
Return _Lastname
End Get
Set(ByVal value As String)
_Lastname = value
End Set
End Property
<XmlAttribute("Emailadres")>
Public Property Email() As String
Get
Return _Email
End Get
Set(ByVal value As String)
_Email = value
End Set
End Property
End Class
Class ContactContainer
Code:
Public Class Contact
'Storage of class Contact data
Private _Firstname As String
Private _Lastname As String
Private _Email As String
<XmlAttribute("Voornaam")>
Public Property Firstname() As String
Get
Return _Firstname
End Get
Set(ByVal value As String)
_Firstname = value
End Set
End Property
<XmlAttribute("Achternaam")>
Public Property Lastname() As String
Get
Return _Lastname
End Get
Set(ByVal value As String)
_Lastname = value
End Set
End Property
<XmlAttribute("Emailadres")>
Public Property Email() As String
Get
Return _Email
End Get
Set(ByVal value As String)
_Email = value
End Set
End Property
End Class
Code:
Public Sub New()
InitializeComponent()
SupportedOrientations = SupportedPageOrientation.Portrait Or SupportedPageOrientation.Landscape
Dim xRoot As XmlRootAttribute = New XmlRootAttribute()
xRoot.Namespace = "AdresboekApp"
xRoot.ElementName = "Adresboek"
xRoot.IsNullable = True
Dim path As String = "Assets\Contacten.xml"
Dim serializer = New XmlSerializer(GetType(List(Of ContactContainer)), xRoot)
Dim streamReader = New FileStream(path, FileMode.Open)
Dim readContainer = TryCast(serializer.Deserialize(streamReader), List(Of ContactContainer))
lls.ItemsSource = readcontainer
streamReader.Close()
End Sub
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|