主頁 > 軟體設計 > 從C#中的Json字串中檢索特定型別的實際具體物件的最佳方法?

從C#中的Json字串中檢索特定型別的實際具體物件的最佳方法?

2022-05-20 17:40:02 軟體設計

我目前正在努力確定 json-string 反序列化器在 C# 中回傳的型別。我試圖創建一個基礎 TypeWHATEVER 類,其中 TypeX 和 TypeY 繼承自它們,但是每當我嘗試檢索具有該特定型別的實際物件時,它仍然不起作用,因為兩者都可以使用相同的建構式創建一個新實體。

假設我有 TypeX 和 TypeY。它們都有相似的建構式,例如:都有一個帶引數的建構式(字串 a,字串 b)。但是,TypeY 有一個帶引數的附加建構式,例如 (string a, string b, string c)。

現在,每當我在 TypeY 中使用額外的建構式,甚至只是使用類似的建構式時,它仍然不會產生我想要的結果(它仍然將它視為 TypeX 和 TypeY)......在其中一種方法中我不知道要回傳哪種型別,因為該物件是從 Json-String 反序列化的。還把 T 和 放在給物件支持的方法上,但它適用于兩個類,這不是我想要的......我什至在每個不同的底層 Type 類中都放了一個列舉,但自從型別也在基類中定義。

如何或什么是確定如何從有類似建構式的 json 字串中獲取實際物件型別的最佳方法,但它們仍然彼此不同......

請幫助我完成這個:(

下面你會找到我想要實作的示例代碼..

就像我之前說的,我有一個基類或介面沒關系,還有兩個子類

基類:例如 Parent.cs

public class Parent
{
    public virtual ClassType Type { get; protected set; } = ClassType.Undefined;//this is an enum and used to differentiate between the different classes. However, this doesn't work, because of the parent type will always be Undefined whenever a child type is converted from json-string to explicit Parent type...
    public string Id { get; set; }
    public string Message { get; set; }

    public Parent()
    {

    }

    public Parent(string id, string message = "")
    {
        Id = id;
        Message = message;
    }
}

子類:例如 ChildA.cs

public class ChildA : Parent
{
    public override ClassType Type => ClassType.Default;

    public ChildA()
    {

    }

    public ChildA(string id, string message = "") : base(id, message)
    {

    }
}

子類:例如 ChildB.cs

    public class ChildB : Parent
{
    private object testObjectA;
    private object testObjectB;
    private object testObjectC;

    public override ClassType Type => ClassType.New;

    public object TestObjectA
    {
        get { return testObjectA; }
        set { testObjectA = value; }
    }

    public object TestObjectB
    {
        get { return testObjectB; }
        set { testObjectB = value; }
    }

    public object TestObjectC
    {
        get { return testObjectC; }
        set { testObjectC = value; }
    }

    public ChildB()
    {

    }

    public ChildB(string id, string message) : base(id, message)
    {

    }

    public ChildB(string id, IDictionary<string, object> collection, string message = "") : this(id, message) // should I use 'this' or 'base' here for id and message, because I already get the base class for the second constructor and it makes sense to me just to take this class since the other is already been using the base class?
    {
        testObjectA = collection[Constants.A];
        testObjectB = collection[Constants.B];
        testObjectC = collection[Constants.C];
    }
}

Json 轉換器類:例如 JsonConverterClass.cs

public static T StringToObject<T>(string json)
        => JsonConvert.DeserializeObject<T>(json);//using Newtonsoft.Json;

現在我有一個想要轉換為 ChildA 或 ChildB 的 Json-String。Json-String 是這樣的:

{
  "type": "New",//This is the ClassType for example
  "id": "Some String...",
  "message": "",
  "collection": {
   "objectA": "A",
   "objectB": "B",
   "objectC": "C",
  }
}

讓我們嘗試轉換不起作用的 Json 字串并將該 Child 物件回傳到一個方法中,不幸的是這不起作用:

public Parent GetObjectExample(string json_String)
    {
        Parent parentClass = JsonConverterClass.StringToObject<Parent>(json_String);// I don't know how I maybe can use reflection here to accomplish, maybe this is an option too?

        switch (parentClass.Type)
        {
            case ClassType.Default:
                parentClass = parentClass as ChildA;
                break;
            case ClassType.New:
                parentClass = parentClass as ChildB;
                break;
        }

        return parentClass;
    }

這里的問題是我希望 ChildB 會回饋。但是,由于兩個類具有相同的建構式。它不承認還給 ChildB。事實上,它只是回傳一個隨機類。 ChildA 或 ChilB,在大多數情況下,它只是回傳 ChildA 真正奇怪的東西。

希望我能盡可能清楚地告訴你發生了什么,我真的不知道為什么我的方法不起作用......

uj5u.com熱心網友回復:

好吧,我想有很多東西要評論。讓我們開始:

在具有 3 個引數的建構式中,使用this而不是base. 想象一下這種情況:

public ChildB(string id, string message) 
    : base(id, message)
{
    this.FullName = $"{id} {message}";
}

public ChildB(string id, IDictionary<string, object> collection, string message = "") 
    : this(id, message)
{
}

呼叫this,您的 3 引數建構式運行設定FullName屬性的 2 引數建構式。如果你使用base,FullName將不會被初始化,你必須在你的 3 引數建構式中復制這一行。

C# 知道任何物件的型別。真的,你不需要你的ClassType財產。您可以執行以下操作:

if (myChildBInstance.GetType() == typeof(ChildB))

我建議您洗掉此屬性。

此外,該財產受到保護。您無法從序列化中更改它的值。序列化(默認情況下)適用于公共屬性。

我認為,您問題的關鍵在于建構式。序列化時,始終使用無引數建構式。在反序列化中,呼叫不帶引數的建構式,然后設定屬性。

Type在 JSON 字串中的屬性永遠不會被使用。您無法設定該值,因為它是受保護的,并且您的實體是在您開始處理這些屬性之前創建的。

var json = @"{
      'type': 'New',//This is the ClassType for example
      'id': 'Some String...',
      'message': '',
      'collection': {
       'objectA': 'A',
       'objectB': 'B',
       'objectC': 'C',
      }
    }";
var obj = StringToObject<ChildB>(json);

當您運行前面的代碼時,ChildB會創建一個物件(因為Ttype of StringToObject),然后設定所有 JSON 字串(公共)屬性。因此,您的 type 屬性不可能對選擇物件的型別有用。collection不是您的物件的屬性:這就是您的物件沒有獲得這些 A、B、C 值的原因。

使用此示例:

var childB = new ChildB
{
    Id = "Id",
    Message = "Msg",
    TestObjectA = 1,
    TestObjectB = 2,
    TestObjectC = 3
};
var json = JsonConvert.SerializeObject(childB);

您的 JSON 必須是這樣的:

{
   "TestObjectA":1,
   "TestObjectB":2,
   "TestObjectC":3,
   "Id":"Id",
   "Message":"Msg"
}

然后,您以這種方式獲得有效物件:

var obj = StringToObject<ChildB>(json);

如果您要使用不同的型別和繼承,那么您必須使用TypeNameHandling = TypeNameHandling.All我在鏈接https://stackoverflow.com/a/72270480/18452174之前評論過的內容。

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/478587.html

標籤:C# 视觉工作室 仿制药 类型

上一篇:git分支末尾的符號(* !)是什么意思?[復制]

下一篇:是否可以在不重建堆的情況下從兩個堆構建最大堆?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more