如何在 VB.NET 中序列化一个列表(对象)?
How to serialize a List(of Object) in VB.NET?
我有一个 class Player
,我用它来创建 List(Of Player)
。我需要在应用程序关闭时保存它。在 Windows 表单中,我只是序列化,但在 UWP 中不再可能,所以我不得不 Google 几十个小时,我终于偶然发现了 Microsoft.Toolkit.Uwp
, then Newtonsoft.Json
,但我失败了悲惨地使用它们。我需要你的帮助!
假设我有一个小 class :
Dim Name As String
Dim Score As Double
Public Class Player
<JsonConstructor()>
Public Sub New(Name As String, Score As Double) ' New with score
Me.Name = Name
Me.Score = Math.Max(1, Score)
End Sub
End Class
Public Overrides Function ToString() As String ' ToString
Return $"{Name} [{Score}]"
End Function
如何成功读写List(Of Player)
?
' Loading MainPage.xaml
Private Sub MainPage_Loading() Handles Me.Loading
ReadAsync()
MainFrame.Margin = New Thickness(0)
Window.Current.Content = MainFrame
MainFrame.Navigate(GetType(PlayerList), Players)
End Sub
' Read
Private Async Sub ReadAsync()
Players = JsonConvert.DeserializeObject(Of List(Of Player))(Await FileIO.ReadTextAsync((Await StorageFolder.CreateFileAsync("players.json", CreationCollisionOption.OpenIfExists))))
If Players Is Nothing Then
Players = New List(Of Player)
WriteAsync()
End If
End Sub
' Write
Public Shared Async Sub WriteAsync()
Await FileIO.WriteTextAsync(Await StorageFolder.CreateFileAsync("players.json", CreationCollisionOption.ReplaceExisting), JsonConvert.SerializeObject(Players, Formatting.Indented))
End Sub
' Loading PlayerList.xaml
Protected Overrides Sub OnNavigatedTo(e As NavigationEventArgs)
ListBoxPlayers.Items.Clear()
Players = e.Parameter
For Each Player In Players
ListBoxPlayers.Items.Add(Player)
Next
End Sub
' Adding a new player in the interface
Private Sub ButtonAddPlayer_Click(sender As Button, e As RoutedEventArgs) Handles ButtonAddPlayer.Click
' ...
' Commit
MainPage.Players.Add(New Player(TextBoxName.Text))
ListBoxPlayers.Items.Add(MainPage.Players(MainPage.Players.Count - 1))
MainPage.WriteAsync()
End Sub
所以这一切都令人困惑。当我通过界面添加播放器时,它会像往常一样进入我的列表框。但是,当我关闭应用程序并重新打开它时,我得到了一些空对象。
我做了一些愤怒的测试以更多地了解我的问题,事实证明我根本没有序列化,但我可能正在正确反序列化。
我找到了,原来它在我的 class Player
.
我用过的:
Dim Name As String
Dim Score As Double
有效的方法:
Public Name As String
Public Score As Double
我应该做的:
Public Property Name As String
Public Property Score As Double
我被教导在 Java 中编码时不要将变量设置为 "public",而且我不知道 Visual Basic 中存在 Property
。
我有一个 class Player
,我用它来创建 List(Of Player)
。我需要在应用程序关闭时保存它。在 Windows 表单中,我只是序列化,但在 UWP 中不再可能,所以我不得不 Google 几十个小时,我终于偶然发现了 Microsoft.Toolkit.Uwp
, then Newtonsoft.Json
,但我失败了悲惨地使用它们。我需要你的帮助!
假设我有一个小 class :
Dim Name As String
Dim Score As Double
Public Class Player
<JsonConstructor()>
Public Sub New(Name As String, Score As Double) ' New with score
Me.Name = Name
Me.Score = Math.Max(1, Score)
End Sub
End Class
Public Overrides Function ToString() As String ' ToString
Return $"{Name} [{Score}]"
End Function
如何成功读写List(Of Player)
?
' Loading MainPage.xaml
Private Sub MainPage_Loading() Handles Me.Loading
ReadAsync()
MainFrame.Margin = New Thickness(0)
Window.Current.Content = MainFrame
MainFrame.Navigate(GetType(PlayerList), Players)
End Sub
' Read
Private Async Sub ReadAsync()
Players = JsonConvert.DeserializeObject(Of List(Of Player))(Await FileIO.ReadTextAsync((Await StorageFolder.CreateFileAsync("players.json", CreationCollisionOption.OpenIfExists))))
If Players Is Nothing Then
Players = New List(Of Player)
WriteAsync()
End If
End Sub
' Write
Public Shared Async Sub WriteAsync()
Await FileIO.WriteTextAsync(Await StorageFolder.CreateFileAsync("players.json", CreationCollisionOption.ReplaceExisting), JsonConvert.SerializeObject(Players, Formatting.Indented))
End Sub
' Loading PlayerList.xaml
Protected Overrides Sub OnNavigatedTo(e As NavigationEventArgs)
ListBoxPlayers.Items.Clear()
Players = e.Parameter
For Each Player In Players
ListBoxPlayers.Items.Add(Player)
Next
End Sub
' Adding a new player in the interface
Private Sub ButtonAddPlayer_Click(sender As Button, e As RoutedEventArgs) Handles ButtonAddPlayer.Click
' ...
' Commit
MainPage.Players.Add(New Player(TextBoxName.Text))
ListBoxPlayers.Items.Add(MainPage.Players(MainPage.Players.Count - 1))
MainPage.WriteAsync()
End Sub
所以这一切都令人困惑。当我通过界面添加播放器时,它会像往常一样进入我的列表框。但是,当我关闭应用程序并重新打开它时,我得到了一些空对象。
我做了一些愤怒的测试以更多地了解我的问题,事实证明我根本没有序列化,但我可能正在正确反序列化。
我找到了,原来它在我的 class Player
.
我用过的:
Dim Name As String
Dim Score As Double
有效的方法:
Public Name As String
Public Score As Double
我应该做的:
Public Property Name As String
Public Property Score As Double
我被教导在 Java 中编码时不要将变量设置为 "public",而且我不知道 Visual Basic 中存在 Property
。