2017-01-20 4 views
0
{ 
    "Class1": { 
     "Class2": [ 
      {"Name": "DerivedV1"}, 
      {"Name": "DerivedV2"}, 
      {"Name": "DerivedV3"} 
     ] 
    } 
} 

JsonConvert.DeserializeObject<Class1>(jsonString, settings); 

public class Class1 
{ 
    public List<BaseClass> DerivedClasses { get; set; } 
} 

public abstract BaseClass 
{ 
    public string Name { get; set; } 

    public abstract bool DoSomething; 
} 

public class DerivedV1 : BaseClass 
{ 
    public override bool DoSomething() 
    { 
     // Logic here, different for each derived class. 
    } 
} 

Class1을 deserialize하려고하면 파생 클래스 목록을 이름에서 분류하는 방법을 알 수 없습니다. ListClassClass와 같은 클래스를 선언 할 수 없습니다. BaseClass는 추상 클래스이며, 클래스 이름을 역 직렬화 중에 리플렉션을 사용하여 "name"값에서 파생 클래스를 결정하는 방법을 모르겠습니다. 나는 또한 ICloneable을 들여다 보았지만이 맥락에서 어디에도 가지 않았다.JSON을 파생 클래스로 비방 화합니다.

편집 :

여기

내가 만들고 얻을에서 전화를 끝내었고,

public static List<T> DeserializeJObjectsToObjects<T>(IEnumerable<JObject> jObjects, string typeKey, string nameSpaceOfClass) 
    { 
     Assembly assembly = Assembly.GetExecutingAssembly(); 
     List<T> convert = new List<T>(); 

     foreach (var jObject in jObjects) 
     { 
      JToken typeName; 
      jObject.TryGetValue(typeKey, out typeName); 
      string fullNameSpace = string.Format(namespaceFormat, nameSpaceOfClass, typeName); 
      Type t = Type.GetType(string.Format(fullNameSpace)); 
      convert.Add((T) Activator.CreateInstance(t)); 
     } 

     return convert; 
    } 

    public static List<JObject> SerializeObjectsToJObjects<T>(IEnumerable<T> variableObjects) 
    { 
     List<JObject> convert = new List<JObject>(); 

     foreach (T variableObject in variableObjects) 
     { 
      var jsonString = JsonConvert.SerializeObject(variableObject); 
      convert.Add(JObject.Parse(jsonString)); 
     } 

     return convert; 
    } 
+0

비 직렬화 중에 시도한 코드를 제공해 주실 수 있습니까? – ragerory

+0

달성하려는 목표는 무엇입니까? 제공 한 JSON을 deserialize 할 때 예상되는 결과는 무엇입니까? – ironstone13

+0

내가 시도한 일부 기본 코드가 추가되었지만 작동하지 않지만 잘하면 무엇을하려고하는지 보여줍니다. – user2680142

답변

0

첫째, 몇 가지 메모를 설정할 것입니다 - 나는 JSonConvert를 사용하지 않는하지만 방법을 보여 기사가 이것을하기 위해서. 예를 들어 Json.net serialize/deserialize derived types?을 참조하십시오. 그러나, 당신은 json.net 태그를 포함하지 않았다. 그래서 나는 이것이 잘하면 도움이 될 것이라고 가정한다.

내장 JavaScriptSerializer를 사용했습니다. 입력 내용에 맞게 조정해야 할 수도 있습니다. 귀하의 코드를 기반으로 입력을 만들었고 내 json은 귀하의 코드처럼 보이지 않습니다. 그래서, 당신은 여전히 ​​약간의 일이 남아있을 수 있습니다. SimpleTypeResolver로 작업 할 수있었습니다. 아래 코드 :합니다 (SimpleTypeResolver와)

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web.Script.Serialization; 
using System.Windows.Forms; 
using System.Xml.Serialization; 

namespace WindowsFormsApplication6 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Class1 oClass = new Class1(); 
     DerivedV1 v1 = new DerivedV1(); 
     v1.Name = "DerivedV1"; 
     oClass.DerivedClasses.Add(v1); 
     DerivedV2 v2 = new DerivedV2(); 
     v2.Name = "DerivedV2"; 
     oClass.DerivedClasses.Add(v2); 
     DerivedV3 v3 = new DerivedV3(); 
     v3.Name = "DerivedV3"; 
     oClass.DerivedClasses.Add(v3); 
     JavaScriptSerializer ser = new JavaScriptSerializer(new SimpleTypeResolver()); 
     string sSer = ser.Serialize(oClass); 

     var test =ser.Deserialize(sSer,typeof(Class1)); 
     foreach (var tst in ((Class1)test).DerivedClasses) 
     { 
      Console.WriteLine(tst.Name + Environment.NewLine); 
      Console.WriteLine(tst.GetType().ToString() + Environment.NewLine); 
     } 
    } 
    public class Class1 
    { 
     public List<BaseClass> DerivedClasses { get; set; } 
     public Class1() 
     { 
      DerivedClasses = new List<BaseClass>(); 
     } 
    } 
    public abstract class BaseClass 
    { 
     public string Name { get; set; } 
     private bool _dosom; 

     public abstract bool DoSomething(); 
     public BaseClass(){} 
    }  
    public class DerivedV1 : BaseClass 
    { 
     public override bool DoSomething() 
     { 
      return true; 
      // Logic here, different for each derived class. 
     } 
    } 
    public class DerivedV2 : BaseClass 
    { 
     public override bool DoSomething() 
     { 
      return false; 
      // Logic here, different for each derived class. 
     } 
    } 
    public class DerivedV3 : BaseClass 
    { 
     public override bool DoSomething() 
     { 
      return true; 
      // Logic here, different for each derived class. 
     } 
    } 
} 
} 

내 출력 JSON :

{"DerivedClasses":[{"Name":"DerivedV1"},{"Name":"DerivedV2"},{"Name":"DerivedV3"}]} 

을 내가 직렬화 번 :

{"__type":"WindowsFormsApplication6.Form1+Class1, WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","DerivedClasses":[{"__type":"WindowsFormsApplication6.Form1+DerivedV1, WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"DerivedV1"},{"__type":"WindowsFormsApplication6.Form1+DerivedV2, WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"DerivedV2"},{"__type":"WindowsFormsApplication6.Form1+DerivedV3, WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"DerivedV3"}]} 

및 유형의 해결없이 비교는 (오류가 발생합니다) (for 루프에서 Console.WriteLine) ...

DerivedV1 

WindowsFormsApplication6.Form1+DerivedV1 

DerivedV2 

WindowsFormsApplication6.Form1+DerivedV2 

DerivedV3 

WindowsFormsApplication6.Form1+DerivedV3 
+0

사용자가 입력 할 때 텍스트에서 직선으로 비 순차화한 경우에는 작동하지 않습니다. 개체에 JavaScriptSerializer를 사용하면 "__type": "WindowsFormsApplication6.Form1 + DerivedV2"와 같은 추가 정보가 추가됩니다. 특정 경우에는 맞지만 내가 원하는 것은 아닙니다 .JSON 템플릿을 쉽게 만들 수 있습니다. – user2680142

+0

예,이 방법으로 일련 번호를 지정해야합니다. 다르지 않은 경우 json 생성 소프트웨어에 액세스해야합니다. json을 생성 할 수 없다면 1을 사용해야합니다. "DoSomething"에 이름 (또는 다른 속성)을 기반으로하는 논리를 사용합니다. 그러나 파생 된 유형을 파생 된 유형을 알려주지 않는 기본 유형의 목록으로 가져 오려면 어떻게해야할까요? 자신의 코드입니다. 기존의 serializer로 할 수있는 방법을 생각해 볼 수 있습니까? – Aaron

+0

생각하지 않습니다. 클래스 형식을 유추 할 값을 지정하는 방법을 보지 못했습니다. 지금 당장 "작동 중"이라면, DervicedClasses에 적합한 BaseClass에 있습니다. ty getter와 setter는 JSON에서 생성 된 JObjects의 비공개 목록을 조작합니다. getter는 Activator를 사용하여 올바른 인스턴스를 만들고 setter는 각 요소를 직렬화하고 목록을 설정합니다. – user2680142

0

내 솔루션으로 사용.

public static List<T> DeserializeJObjectsToObjects<T>(IEnumerable<JObject> jObjects, string typeKey, string nameSpaceOfClass) 
    { 
     Assembly assembly = Assembly.GetExecutingAssembly(); 
     List<T> convert = new List<T>(); 

     foreach (var jObject in jObjects) 
     { 
      JToken typeName; 
      jObject.TryGetValue(typeKey, out typeName); 
      string fullNameSpace = string.Format(nameSpaceFormat, nameSpaceOfClass, typeName); 
      Type t = Type.GetType(string.Format(fullNameSpace)); 
      convert.Add((T) Activator.CreateInstance(t)); 
     } 

     return convert; 
    } 

    public static List<JObject> SerializeObjectsToJObjects<T>(IEnumerable<T> variableObjects) 
    { 
     List<JObject> convert = new List<JObject>(); 

     foreach (T variableObject in variableObjects) 
     { 
      var jsonString = JsonConvert.SerializeObject(variableObject); 
      convert.Add(JObject.Parse(jsonString)); 
     } 

     return convert; 
    } 
관련 문제