|
-
July 21st, 2011, 03:54 PM
#1
Serialization Problem help please
Hi all, I'm having trouble understanding object serialization, I've read about it a good amount and tried to apply it in a program i previously mad with no avail. The program consists of a Customers class that is a List<Customer>. I marked both Customers and Customer with the serialize attribute and authored helper functions to SaveCustomers() before program termination and RetrieveCustomers() as soon as the program created and instance of Customers to which I can Deserialize too.
The problem is when I run the program it does not deserialize and populate my list. The list remains empty.
Here are the two classes im trying to serialize:
Code:
[Serializable]
class Customers : List<Customer>
{
public int Total { get { return this.Count; } } // Read-only propety returns number of customers in the list (this.Count inherited from List class).
private static string tempphone;
public static string temp_phone
{
get { return tempphone; }
set
{
if (value.Length < 20)
tempphone = value;
else
{
tempphone = null;
Console.WriteLine("Device name too long. Customer will not be registered.");
}
}
}
private static string tempname;
public static string temp_name
{
get { return tempname; }
set
{
if (value.Length < 25)
tempname = value;
else
{
tempname = null;
Console.WriteLine("Customer name too long. Customer will not be registered.");
}
}
}
//Methods
public void AddCustomer(string name, string phone)
{
Console.Write("\n");
temp_name = name;
temp_phone = phone;
if (temp_name != null && temp_phone != null)
{
this.Add(new Customer(this.Total + 1, name, phone));
Console.WriteLine("Customer successfully registered with ID number: {0}", this.Total);
}
else Console.WriteLine("Customer registry unsuccessfull.\n");
}
public void Store(int id, Slot s)
{
// this.First returns the first customer in Customers List that meets lambda expression requirements.
Customer thiscustomer = this.First( Customer => Customer.idnumber == id); // Lambda Expression: "find Customer where Customer.idnumber matches the provided ID number."
if (thiscustomer != null)
thiscustomer.storeDevice(s);
}
public void Unstore(int id, Slot s)
{
Customer thiscustomer = this.First(Customer => Customer.idnumber == id);
if (thiscustomer != null)
thiscustomer.unStoreDevice(s);
}
public void ViewCustomer(int id)
{
if (id <= Total)
{
Customer thiscustomer = this.First(Customer => Customer.idnumber == id);
if (thiscustomer != null)
thiscustomer.viewCustomer();
}
else Console.WriteLine("That ID number has not been registered yet.");
}
public void EditCustomer(int id)
{
Customer thiscustomer = this.First(Customer => Customer.idnumber == id);
thiscustomer.editCustomer();
}
}
[Serializable]
class Customer
{
public string name { get; set; }
private string[] device_Array;
public string[] deviceArray
{
get { return device_Array; }
set
{
device_Array = value;
}
}
public int idnumber { get; set; }
public string location { get; set; }
// Constructor
public Customer(int id, string n = " ", string phone = " ")
{
idnumber = id;
name = n; // When defining a property for a value type, you may use it right away. (value set to default otherwise)
deviceArray = new string[3]; // When defining a property for a reference type, must intialize is with new in constructor before use (value set to null otherwise)
deviceArray[0] = phone;
deviceArray[1] = null;
deviceArray[2] = null;
location = "None";
}
public void storeDevice(Slot emptyslot)
{
emptyslot.idnumber = this.idnumber; // Sets slot to customer ID.
this.location = emptyslot.slot; // Set location of customer.
Console.WriteLine("Customer device successfully stored at: {0}", emptyslot.slot);
}
public void unStoreDevice(Slot fullslot)
{
fullslot.idnumber = null; // Frees slot
this.location = null; // Sets Customer location to null.
Console.WriteLine("Customer device successfully unstored from: {0}", fullslot.slot);
}
public void viewCustomer()
{
Console.Write("\n");
Console.WriteLine("Name: {0}", name);
Console.WriteLine("Device: {0}, {1}, {2}", deviceArray[0], deviceArray[1], deviceArray[2]);
Console.WriteLine("ID Number: {0}", idnumber);
Console.WriteLine("Location: {0}", location);
}
public void editCustomer()
{
Console.WriteLine("Press 1 to change customer name\nPress 2 to change customer device\nPress 3 to add another customer device.");
Console.Write("Choice: ");
int choice = int.Parse(Console.ReadLine());
Console.Write("\n");
string temp = null;
switch (choice)
{
case 1:
Console.WriteLine("Enter new name: ");
name = Console.ReadLine();
Console.WriteLine("Name successfully changed.\n");
break;
case 2:
Console.WriteLine("Which device would you like to change?\n1. {0}\n2. {1}\n3. {2}", deviceArray[0], deviceArray[1], deviceArray[2]);
Console.Write("\n\nChoice: ");
choice = int.Parse(Console.ReadLine());
Console.WriteLine("Enter new device: ");
deviceArray[choice - 1] = Console.ReadLine();
Console.WriteLine("Device successfully changed.\n");
// Code to edit CustomerRegistry.
break;
case 3:
if (deviceArray[1] != null && deviceArray[2] != null)
{
Console.WriteLine("3 device limit reached. Cannot add another device.");
break;
}
Console.WriteLine("Enter additional device to store: ");
if (deviceArray[1] == null)
{
deviceArray[1] = Console.ReadLine();
Console.WriteLine("Second device successfully added.\n");
// Code to edit CustomerRegistry.
}
else if (deviceArray[2] == null)
{
deviceArray[2] = Console.ReadLine();
Console.WriteLine("Third device successfully added.\n");
// Code to edit CustomerRegistry.
}
break;
default:
Console.WriteLine("Not a valid choice.\n");
break;
}
}
public override string ToString()
{
return string.Format("{0} {1} {2} {3} {4}", idnumber, name, deviceArray[0], deviceArray[1], deviceArray[2]);
}
}//End CUstomer Class
And here is main and the helper functions:
Code:
static void Main()
{
Customers customerList = new Customers();
RetrieveCustomers(customerList, "Customer Registry.dat");
//////Program Runs //////
//Before Exit//
SaveCustomers(customerList, "Customer Registry.dat");
}
public static void SaveCustomers(object objGraph, string fileName)
{
BinaryFormatter bnFormatter = new BinaryFormatter();
using (Stream fstream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
bnFormatter.Serialize(fstream, objGraph);
}
}
public static void RetrieveCustomers(Customers list, string fileName)
{
BinaryFormatter bnFormatter = new BinaryFormatter();
try
{
using (Stream fstream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
list = (Customers)bnFormatter.Deserialize(fstream);
}
}
catch (Exception e)
{
Console.WriteLine("Customer List not populated. File does not exist yet");
}
}
And help would be greatly appreciated. I know i left out a lot of code including a Storage: List<Slot> and Slot classes. Let me know if you need me to post them.
Thank you in advance.
-
July 22nd, 2011, 05:44 AM
#2
Re: Serialization Problem help please
It si because serialization of generics are gliched. To overcome it, you have to implement ISerializable interface, but in your case, it should be sufficient to change the type of the collection from List<Customer> to Customer[] for the serialization.
- Make it run.
- Make it right.
- Make it fast.
Don't hesitate to rate my post. 
-
July 22nd, 2011, 12:31 PM
#3
Re: Serialization Problem help please
 Originally Posted by boudino
It si because serialization of generics are gliched. To overcome it, you have to implement ISerializable interface, but in your case, it should be sufficient to change the type of the collection from List<Customer> to Customer[] for the serialization.
Yes, rather than deriving your class from List<Customer>, just make a private List<Customer> field, and expose it as a Customer[] property using List<>.ToArray() and List<>.SetRange().
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
|