Newtonsoft反序列化和属性Getter方法

时间:2015-09-23 02:05:31

标签: c# json-deserialization

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();时,为什么解串器无法做到?

1 个答案:

答案 0 :(得分:4)

因为 -

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

只要属性为null,就会创建一个新属性。但它不会更新_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,则使用新对象初始化该属性,并将其分配给成员_property。将来,无论何时使用此属性,它都具有适当的引用并且可以正常工作。

BTW:这不是问题。这是必需的行为。