Reputation: 251
I have a class which i want to serialize and deserialize with binaryformat. But i get error while deserializing.
This is my object to serialize
using CizelgelemeDesktop.GeneticAlgorithm;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;**strong text**
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace CizelgelemeDesktop
{
[Serializable()]
public class ObjectToSerialize : ISerializable
{
private Chromosom chromosom;
private string name="isimsiz";
public string Name
{
get { return name; }
set { name = value; }
}
public Chromosom Chromosom
{
get { return chromosom; }
set { chromosom = value; }
}
public ObjectToSerialize(Chromosom c, Sources.Sources s)
{
chromosom = c;
}
public ObjectToSerialize(SerializationInfo info, StreamingContext context)
{
chromosom = (Chromosom)info.GetValue("Chromosom",chromosom.GetType());
name = (string)info.GetValue("Name",name.GetType());
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Chromosom", chromosom);
info.AddValue("Name", name);
}
public static void SaveToFile(ObjectToSerialize o, string path)
{
using (FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate))
{
BinaryFormatter binFormatter = new BinaryFormatter();
binFormatter.Serialize(fileStream, o);
}
}
public static ObjectToSerialize LoadFromFile(string path)
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(path, FileMode.Open);
BinaryFormatter binFormatter = new BinaryFormatter();
return (ObjectToSerialize)binFormatter.Deserialize(fileStream);
}
catch (Exception exc)
{
return null;
}
finally
{
if (fileStream != null) fileStream.Close();
}
}
}
}
This my Choromosom.cs
using CizelgelemeDesktop.Sources;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace CizelgelemeDesktop.GeneticAlgorithm
{
[Serializable()]
public class Chromosom : ISerializable
{
public Hashtable classes;
public List<CourseClass>[] slots;
public float fitnessValue;
public bool feasible;
public bool[] criterias;
public int yil;
public int donem;
private int numberOfRooms;
[NonSerialized()]Random rnd;
public Chromosom(int nr)
{
rnd = new Random();
numberOfRooms = nr;
classes = new Hashtable();
int slotSize = Sources.Sources.NumberOfDays * Sources.Sources.HoursPerDay * numberOfRooms;
slots = new List<CourseClass>[slotSize];
for (int i = 0; i < slotSize; i++)
{
slots[i] = new List<CourseClass>();
}
}
/// <summary>
///
/// </summary>
/// <param name="nr" number of rooms></param>
public void Mutation(GA ga)
{
if (rnd.Next(100) > Sources.Sources.MutationProbability)
return;
//Selective Mutation
int nr=ga.sources.Derslikler.Count;
for (int a = 0 ; a < 5 ; a++ )
{
int index = rnd.Next(ga.sources.CourseClasses.Count);
//determine new position to class
CourseClass cc = (CourseClass)ga.sources.CourseClasses[index];
int pos1 = (int)classes[cc];
int dur = cc.duration;
int day;
int room = rnd.Next(nr);
int time;
///check İzinler
bool hata = false;
while (true)
{
hata = false;
day = rnd.Next(Sources.Sources.NumberOfDays);
time = rnd.Next(Sources.Sources.HoursPerDay - dur + 1);
for (int i = dur - 1; i >= 0; i--)
{
if (cc.prof.izinler[day * 15 + time + i] == 1)
hata = true;
}
if (!hata)
break;
}
///end İzinler
int pos2 = day * nr * Sources.Sources.HoursPerDay + room * Sources.Sources.HoursPerDay + time;
//move slot values
for (int i = 0; i < dur; i++)
{
slots[pos1 + i].Remove(cc);
slots[pos2 + i].Add(cc);
}
//change the entry of classes table
classes[cc] = pos2;
}
}
public void Mutation2(GA ga)
{
List<int> indexList = new List<int>();
int index = -1;
for (int i = 0; i < criterias.Length; i++)
{
if (criterias[i])
{
indexList.Add(i);
}
}
if (indexList.Count<1)
return;
index = indexList[rnd.Next(indexList.Count)];
index /= Sources.Sources.numberOfConstraints;
CourseClass cc = ga.sources.CourseClasses[index];
int daySize = Sources.Sources.HoursPerDay * ga.sources.Derslikler.Count;
int currentValue = (int)classes[cc];
int lastValue = (int)classes[cc];
int bestValue = (int)classes[cc];
float bestFitness=0;
for (int i = 0; i < slots.Length; i++)
{
if (i == currentValue)
continue;
//check İzinler
int day = i / daySize;
int time = i % Sources.Sources.HoursPerDay;
bool hata=false;
for (int a = cc.duration-1; a >=0; a--)
{
if (cc.prof.izinler[day * 15 + time + a] == 1)
{
hata = true;
break;
}
}
if (hata)
continue;
//end İzinler
if (time + cc.duration > Sources.Sources.HoursPerDay)
continue;
classes[cc] = i;
for (int j = cc.duration-1; j >=0; j--)
{
slots[lastValue+j].Remove(cc);
slots[i+j].Add(cc);
}
lastValue = i;
ga.CalculateFitness(this);
if (fitnessValue > bestFitness)
{
bestFitness = fitnessValue;
bestValue = i;
}
}
classes[cc] = bestValue;
for (int j = cc.duration - 1; j >= 0; j--)
{
slots[lastValue + j].Remove(cc);
slots[bestValue + j].Add(cc);
}
ga.CalculateFitness(this);
}
public void FillSlots()
{
foreach (DictionaryEntry item in classes)
{
CourseClass cc = (CourseClass)item.Key;
int dur = cc.duration;
int value = (int)item.Value;
for (int i = 0; i <dur; i++)
{
slots[value + i].Add(cc);
}
}
}
public Chromosom(SerializationInfo info, StreamingContext context)
{
classes = (Hashtable)info.GetValue("classes", classes.GetType());
slots = (List<CourseClass>[])info.GetValue("slots",slots.GetType());
fitnessValue = (float)info.GetValue("fitnessValue",fitnessValue.GetType());
feasible = info.GetBoolean("feasible");
criterias = (bool[])info.GetValue("criterias", criterias.GetType());
numberOfRooms = info.GetInt32("numberOfRooms");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("classes",classes);
info.AddValue("slots",slots);
info.AddValue("fitnessValue",fitnessValue);
info.AddValue("feasible",feasible);
info.AddValue("criterias", criterias);
info.AddValue("numberOfRooms", numberOfRooms);
}
}
}
This is CourseClass.cs
using CizelgelemeDesktop.GeneticAlgorithm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace CizelgelemeDesktop.Sources
{
[Serializable()]
public class CourseClass : ISerializable
{
public bool lab;
public Prof prof;
public int nufus;
public int duration;
public CourseClass()
{
gruplar = new List<OgrenciGrubu>();
}
public CourseClass(SerializationInfo info, StreamingContext context)
{
lab = info.GetBoolean("lab");
prof = (Prof)info.GetValue("prof", prof.GetType());
nufus = info.GetInt32("nufus");
duration = info.GetInt32("duration");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("lab", lab);
info.AddValue("prof", prof);
info.AddValue("nufus", nufus);
info.AddValue("duration",duration);
}
}
}
Error Log
System.Reflection.TargetInvocationException was unhandled
HResult=-2146232828
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle.SerializationInvoke(IRuntimeMethodInfo method, Object target, SerializationInfo info, StreamingContext& context)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at CizelgelemeDesktop.ObjectToSerialize.LoadFromFile(String path) in d:\Work\ServerGlobal\CizelgelemeDesktop\CizelgelemeDesktop\CizelgelemeDesktop\ObjectToSerialize.cs:line 59
at CizelgelemeDesktop.frmDetay.tsOpen_Click(Object sender, EventArgs e) in d:\Work\ServerGlobal\CizelgelemeDesktop\CizelgelemeDesktop\CizelgelemeDesktop\frmDetay.cs:line 206
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at CizelgelemeDesktop.Program.Main() in d:\Work\ServerGlobal\CizelgelemeDesktop\CizelgelemeDesktop\CizelgelemeDesktop\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.NullReferenceException
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=CizelgelemeDesktop
StackTrace:
at CizelgelemeDesktop.Sources.Prof..ctor(SerializationInfo info, StreamingContext context) in d:\Work\ServerGlobal\CizelgelemeDesktop\CizelgelemeDesktop\CizelgelemeDesktop\Sources\Prof.cs:line 29
InnerException:
I think this is about the generic list fields, but I dont know the solutions. Is there anyone who knows the solution?
Upvotes: 0
Views: 2278
Reputation: 116711
This line will throw a NullReferenceException
:
public CourseClass(SerializationInfo info, StreamingContext context)
{
prof = (Prof)info.GetValue("prof", prof.GetType());
}
The problem is that you are calling prof.GetType()
before the value of prof
has been assigned. Thus it will have its default value of null
.
Upon further inspection, you are doing this in many places. E.g. both name
and chromosom
are not assigned until after info.GetValue()
returns:
public ObjectToSerialize(SerializationInfo info, StreamingContext context)
{
chromosom = (Chromosom)info.GetValue("Chromosom",chromosom.GetType());
name = (string)info.GetValue("Name",name.GetType());
}
Anywhere you do this will throw a NullReferenceException
.
You have to know the type of object you want to store in the class being deserialized, and pass that correct type. See here or here.
From the documentation for SerializationInfo.GetValue(string, Type)
:
If the data stored in the SerializationInfo is of the type requested (or one of its derived classes), that value is returned directly. Otherwise, IFormatterConverter.Convert is called to convert it to the appropriate type.
The value returned by the GetValue method can always be safely cast to the type specified in the type parameter.
Thus, for instance. the deserialization constructor for CourseClass
would be fixed as follows:
public CourseClass(SerializationInfo info, StreamingContext context)
{
lab = info.GetBoolean("lab");
prof = (Prof)info.GetValue("prof", typeof(Prof)); // use typeof(Prof)
nufus = info.GetInt32("nufus");
duration = info.GetInt32("duration");
}
You'll need to go through your code and fix all the places you did this.
Upvotes: 2