2014-10-18 10 views
0

나는 serialize하고 binaryformat을 사용하여 deserialize하려는 클래스가 있습니다. 하지만 deserializing하는 동안 오류가 발생합니다. 직렬화 및 역 직렬화 일반 목록 필드

이 내 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); 
     } 
    } 
} 

이 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); 
     } 
    } 
} 

오류 로그

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: 
,536을

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(); 
      } 
     } 
    } 
} 

를 직렬화 내 개체입니다

제 생각에 이것은 일반적인 목록 필드에 관한 것이지만 해결책을 모릅니다. 해결책을 아는 사람이 있습니까?

+0

왜 BinaryFormatter를 사용합니까? 특수한 생성자 (* SerializationInfo *)와 * GetObjectData *를 쓰지 않고 한 줄에 serializer가 있습니다. –

+0

무엇을 사용해야합니까? – ahmetsarias

+0

[Json.Net] (https : // json .codeplex.com /). 'JsonConvert.SerializeObject','JsonConvert.DeserializeObject'와 같은 것 –

답변

1

이 줄은 NullReferenceException 발생합니다 :

public CourseClass(SerializationInfo info, StreamingContext context) 
    { 
     prof = (Prof)info.GetValue("prof", prof.GetType()); 
    } 

문제는 prof의 값이 할당되기 전에 당신이 prof.GetType()를 호출하는 것입니다. 따라서 기본값은 null입니다.

추가 검사시, 여러 곳에서이 작업을 수행하고 있습니다. 예 : 모두 namechromosom은하지 info.GetValue() 반환 때까지 할당됩니다

public ObjectToSerialize(SerializationInfo info, StreamingContext context) 
    { 
     chromosom = (Chromosom)info.GetValue("Chromosom",chromosom.GetType()); 
     name = (string)info.GetValue("Name",name.GetType()); 
    } 

는 어느 곳이이 NullReferenceException을 던질 것이다 않습니다.

deserialize중인 클래스에 저장할 개체 유형을 알고 올바른 형식을 전달해야합니다. here 또는 here을 참조하십시오. 문서에서

SerializationInfo.GetValue(string, Type)

SerializationInfo에 저장된 데이터를 요구 된 형태의 경우

(또는 유도 클래스 중 하나), 그 값을 직접 리턴한다. 그렇지 않으면 IFormatterConverter.Convert가 호출되어 해당 형식으로 변환됩니다.

GetValue 메서드에서 반환 된 값은 항상 type 매개 변수에 지정된 형식으로 안전하게 캐스팅 할 수 있습니다.

따라서, 예를 들어.

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"); 
    } 

당신은 당신의 코드를 통해 가서 당신이 한 모든 장소를 수정해야합니다 다음과 같이 CourseClass에 대한 직렬화 생성자는 해결 될 것입니다.

+1

Ok. 나는 지금 노력하고있다 – ahmetsarias

+0

그래, 효과가있다. 대단히 감사합니다. – ahmetsarias