c# - Newtonsoft反序列化和属性getter方法

标签 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!'
// ''

为什么反序列化器不能在我执行 return _property ?? new Property(); 时执行它的操作在 getter 方法中?

最佳答案

因为-

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
    }
}

如果属性为空,则用新对象初始化属性,并分配给成员_property。将来无论何时您使用此属性,它都有正确的引用并正常工作。

顺便说一句:这不是问题。这是必需的行为。

关于c# - Newtonsoft反序列化和属性getter方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32729858/

相关文章:

java - 如何忽略导致 jackson 反序列化错误的列表条目?

c# - 文件上传状态指示器 ASP.Net C#

c# - 使用 C# 更新或删除 CSV 中的一行

java - 如何使用 Jackson 的本地化小数点分隔符反序列化浮点值

java - Jackson解析错误: exception org. codehaus.jackson.map.exc.UnrecognizedPropertyException:无法识别的字段 "Results"

javascript - 将字符串文字解析为枚举数组

c# - ASP.net 中的 Entity Framework

C# Entity Framework 4 Common Language Runtime 检测到无效程序错误?

c# - C# 中的列表转换

c# - 如何使用合约解析器和值提供者在反序列化过程中自定义值设置