iT邦幫忙

0

A類別實作interface,各類別繼承A類別,但各類別有各自不同屬性,如何成功用A類別反序列化

請問各位前輩

如果今天有:介面、類別A(實作介面)、多個其他類別(繼承類別A)

介面的屬性:id、type
類別A的屬性:id、type、date
其他類別繼承類別A的各類別則有各自不同的屬性

預計想要產出的json結構為:id、type、date、data{各類別各自不同的屬性←此處可能有多個屬性}

原先採取的方式是在各類別內都新增一個 List<各類別> data {get;set;}
這個方式產出來的json結構雖然對了
但是要將反序列化時用
var a = JsonConvert.DeserializeObject<List<類別A>>(json);
會丟失data下的資料

在類別A下新增List<?> data {get;set;}
由於各類別結構不同,這個List<?>的類別(class)就不曉得該如何填入
要保持json的結構一致的話沒辦法指定各類別的結構並將data更名(無法共用物件名稱data,還是可以?)

目標是:

  1. json結構一致(id type date data{各類別各自屬性})
  2. 反序列化時使用單一類別(做得到嗎?)

描述有點雜亂,如果有謬誤或是需要補充還請不吝提出
謝謝!

看更多先前的討論...收起先前的討論...
fillano iT邦超人 1 級 ‧ 2021-12-02 15:23:42 檢舉
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConvert.htm
fillano iT邦超人 1 級 ‧ 2021-12-02 15:32:27 檢舉
現在不知道怎樣,記得Java的interface當初是無法定義property的,雖然C#可以,但應該也很少人用。因為interface是用來規範一致的方法的,而且這些方法是抽象的,所以只有名稱沒有實做,這樣跟property通常不會扯上關係。
To fillano
目前暫時不考慮在宣告list時使用Object,或是反序列化時使用dynamic
如果都要定義明確屬性的話,似乎就無法在介面或是父類別中定義
但在各繼承類別內宣告,還是踩到反序列化時屬性丟失的問題...
補充一下:
預計想要產出的json結構為:id、type、date、data{各類別各自不同的屬性←此處可能會有多個屬性}
fillano iT邦超人 1 級 ‧ 2021-12-02 16:12:40 檢舉
object是在父類在用,讓子類可以有自己的實做。在子類中,那當然要用concrete class。
在父類別中宣告List<object> data {get;set;}
但在子類別 內無法變成 data = new List<子類別>();
意即無法在父類宣告成object,並依照各子類別特定結構塞東西
想想應該也不可能 囧
fillano iT邦超人 1 級 ‧ 2021-12-02 16:57:03 檢舉
你要自己寫JsonConverter,然後傳給JsonConvert.Deserialize()當作參數。詳細你看一下文件,還有網上找一找怎麼寫。

2 個回答

0
powerc
iT邦新手 4 級 ‧ 2021-12-02 17:40:27

在類別A下新增List<?> data {get;set;}
由於各類別結構不同,這個List<?>的類別(class)就不曉得該如何填入
要保持json的結構一致的話沒辦法指定各類別的結構並將data更名(無法共用物件名稱data,還是可以?)

泛型呢?
官方文件

在父類別宣告List<子類別> data ← 名稱無法重複使用在每一個子類別上
這樣json的結構就會亂掉了...

powerc iT邦新手 4 級 ‧ 2021-12-03 09:24:07 檢舉

joey19930809 可以更詳細的描述你要的結果嗎? 試著直接寫出json結構

To powerc
https://ithelp.ithome.com.tw/questions/10206777
幾乎一樣的問題我又重發一篇文,請你移駕到此處看
如有需要補充的地方還請不吝提出!

4
qaz11226633
iT邦新手 5 級 ‧ 2021-12-03 08:31:13
interface IInterface
        {
            string Id { get; set; }
            int Type { get; set; }
        }

        class AClass<T> : IInterface
        {
            public DateTime Date { get; set; }

            public string Id { get; set; }
            public int Type { get; set; }

            public T Data { get; set; }
        }

        class BClass
        {
            public string str = "IsBClass";
        }
        class CClass
        {
            public string str = "IsCClass";
        }
AClass<BClass> bClass = new AClass<BClass>
            {
                Id = "B",
                Type = 1,
                Date = DateTime.Now,
                Data = new BClass()
            };

            AClass<CClass> cClass = new AClass<CClass>
            {
                Id = "c",
                Type = 2,
                Date = DateTime.Now,
                Data = new CClass()
            };

            string bJson = JsonConvert.SerializeObject(bClass);
            string cJson = JsonConvert.SerializeObject(cClass);
            Console.WriteLine(bJson);
            Console.WriteLine(cJson);

            AClass<BClass> newBClass = JsonConvert.DeserializeObject<AClass<BClass>>(bJson);
            AClass<CClass> newCClass = JsonConvert.DeserializeObject<AClass<CClass>>(cJson);

https://ithelp.ithome.com.tw/upload/images/20211203/20127405Kapo7fUTII.png
https://ithelp.ithome.com.tw/upload/images/20211203/20127405f68UtMry4U.png
https://ithelp.ithome.com.tw/upload/images/20211203/20127405noo6pdHUke.png

我要發表回答

立即登入回答