Newtonsoft反序列化和属性Getter方法

本文关键字:Getter 方法 属性 反序列化 Newtonsoft | 更新日期: 2023-09-27 18:14:18

Newtonsoft的json反序列化器,JsonConvert.DeserializeObject<T>(json);是反序列化我的对象错误,因为它不会实例化属性之一。我写了一个dotnetfiddle,显示了同样的问题。

类:

public class Right
{
    private Property _property;
    public Property Property 
    { 
        get { return _property; } 
        set { _property = value ?? new Property(); } 
    }
}
public class Wrong
{
    private Property _property;
    public Property Property  
    { 
        get { return _property ?? new Property(); } 
        set { _property = value; } 
    }
}
public class Property
{
    public string Text { get; set; }
}
主程序:

using System;
using Newtonsoft.Json;
public class Program
{
    public static void Main()
    {
        //Instantiate
        var right = new Right();
        var wrong = new Wrong();
        //Initialize property
        right.Property = new Property() { Text = "Right!" };
        wrong.Property = new Property() { Text = "Wrong?" };
        //Serialize
        var jsonRight = JsonConvert.SerializeObject(right);
        var jsonWrong = JsonConvert.SerializeObject(wrong);
        //Print json
        Console.WriteLine(jsonRight);       
        Console.WriteLine(jsonWrong);
        //Deserialize
        var dRight = JsonConvert.DeserializeObject<Right>(jsonRight);
        var dWrong = JsonConvert.DeserializeObject<Wrong>(jsonWrong);
        //Print property
        Console.WriteLine("'" + dRight.Property.Text + "'");
        Console.WriteLine("'" + dWrong.Property.Text + "'");
    }
}
输出:

// {"Property":{"Text":"Right!"}}
// {"Property":{"Text":"Wrong?"}}
// 'Right!'
// ''

为什么当我在getter方法中做return _property ?? new Property();时,反序列化器不能做它的事情?

Newtonsoft反序列化和属性Getter方法

因为-

public class Wrong
{
    private Property _property;
    public Property Property  
    { 
        get { return _property ?? new Property(); } // no assignment done to _property.
        set { _property = value; } 
    }
}

当属性为空时创建一个新属性。但它没有更新_property成员,它仍然是旧的,仍然是空的。每次你使用属性时它都会创建一个新对象并返回它并在超出作用域时忘记引用。不管你用的是Json Converter还是别的什么都没关系。这是一个非常非常非常具有破坏性的方法

正确的方法是这个-

public class Right
{
    private Property _property;
    public Property Property 
    { 
        get { return _property; } 
        set { _property = value ?? new Property(); }  //initialized and assigned to _property
    }
}

如果属性为null,则用new object初始化属性,并赋值给成员_property。以后无论你什么时候使用这个属性,它都有正确的引用并能正常工作。

顺便说一句:这不是问题。