如何反序列化文件中的数据并将其投射回原始对象?

时间:2018-11-30 13:12:43

标签: c# serialization

由于某种原因,当我尝试编写代码以将数据反序列化回对象时,我不断收到错误消息“无法将类型方法转换为Form1.Account”。我试图做一个明确的演员表,但这也不起作用。有人可以告诉我我在做什么错。从下面的屏幕快照中可以看到,我的对象是帐户

enter image description here

这是我要反序列化并投射回对象帐户的序列化数据(我理解正确吗?)

enter image description here

这是最初创建帐户(对象)以及序列化数据的代码。

        private int _nextIndex = 0;
    List<Account> accounts = new List<Account>();

    const string FILENAME = "Data.ser";
    FileStream outFile = new FileStream(FILENAME,
        FileMode.Create, FileAccess.Write);
    BinaryFormatter bFormatter = new BinaryFormatter();

            if (checkingRadioButton1.Checked == true)
            {
                _nextIndex++;
                transactionLabel3.Text = "Checking Account: #" + _nextIndex + " created with a starting balance of $" + balance;
                accountTextBox1.Text = "" + _nextIndex;
                accounts.Add(new CheckingAccount(balance)
                {
                    AccountID = _nextIndex
                    ,
                    Student = isStudent
                });
                bFormatter.Serialize(outFile, accounts);
            }
            else if (savingsRadioButton2.Checked == true)
            {
                _nextIndex++;
                transactionLabel3.Text = "Savings Account: #" + _nextIndex + "  created with a starting balance of $" + balance;
                accountTextBox1.Text = "" + _nextIndex;
                accounts.Add(new SavingsAccount(balance)

                {
                    AccountID = _nextIndex
                   ,
                    Senior = isSenior
                });
                bFormatter.Serialize(outFile, accounts);
            }

下面的代码也对数据进行序列化,最后我试图对数据进行反序列化,但是我不断收到上面提到的错误。

            if (depositRadioButton3.Checked == true)
            {
                selectedAccount.DepositFunds(amount);
                bFormatter.Serialize(outFile, accounts);
                transactionLabel3.Text = $"Account: #{selectedAccount.AccountID} You made a deposit of ${amount}";
            }
            else if (withdrawRadioButton4.Checked == true)
            {
                var balance = selectedAccount.GetAvailableBalanceForAccount(accountID);
                if (selectedAccount.HasAvailableFunds && amount <= balance)
                {
                    selectedAccount.WithdrawFromAccount(amount);
                    bFormatter.Serialize(outFile, accounts);
                    transactionLabel3.Text = $"Account: #{selectedAccount.AccountID} You made a withdrawal of ${amount}";
                    outFile.Close();
                    FileStream inFile = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
                    while (inFile.Position < inFile.Length)
                    {
                        accounts = (Account)bFormatter.Deserialize,(inFile);
                        accounts.

                    }
                }

1 个答案:

答案 0 :(得分:4)

您似乎对列表或数组进行了序列化-很有可能是List<Account>。我说这是因为它说“ Count:1”。

有两种方法可以进行此操作:

  1. 尝试:var list = (List<Account>)bFormatter.Deserialize(inFile);(并将其存储在某个地方,大概又回到accounts字段中)

  2. ,或者检查对象:object obj = bFormatter.Deserialize(inFile); Console.WriteLine(obj.GetType().FullName);

请注意:根据您代码中的List<Account> accounts = new List<Account>();,“ 1”可能会正常工作。

我还应该补充一点,我通常建议使用BinaryFormatter反对 。当您对类型进行版本控制时,它非常脆弱且不友好,我已经看到很多人对此有问题。也容易将意外对象意外地吸入序列化图中,尤其是通过事件。我还建议使用其他序列化工具-一系列值得信赖的xml,json,protobuf等序列化程序,这些序列化程序很轻松自如。就个人而言,我偏向于protobuf-net,但是...再次:偏见。