Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Newtonsoft Json序列化循环引用_C#_Serialization_Json.net_Deserialization - Fatal编程技术网

C# 使用Newtonsoft Json序列化循环引用

C# 使用Newtonsoft Json序列化循环引用,c#,serialization,json.net,deserialization,C#,Serialization,Json.net,Deserialization,我尝试序列化和反序列化的实体: public class Car { public string Model { get; set; } public DateTime Year { get; set; } public List<string> Features { get; set; } private Car _car; public Car Car1 { get { re

我尝试序列化和反序列化的实体:

public class Car
{
    public string Model { get; set; }
    public DateTime Year { get; set; }
    public List<string> Features { get; set; }

    private Car _car;
    public Car Car1
    {
        get
        {
            return _car != null ? _car : new Car();
        }
        set
        {
            _car = value;
        }
    }
}
大多数其他地方都提到了使用下面的解决方案,但没有一个是适合我的

var _jsonSettings = new JsonSerializerSettings()
{
    TypeNameHandling = TypeNameHandling.Auto,
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
    ObjectCreationHandling = ObjectCreationHandling.Auto
};

var settings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.Objects
};

settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;

var serialize = JsonConvert.SerializeObject(car, _jsonSettings);

or

var serialize = JsonConvert.SerializeObject(car, settings);
我知道问题出在这里

private Car _car;
    public Car Car1
    {
        get
        {
            return _car != null ? _car : new Car();
        }
        set
        {
            _car = value;
        }
    }
但我现在还不能摆脱它

修改的问题:

public interface IEntity
    {
        int Id { get; set; }
    }
    public class Base1 : IEntity
    {
        public virtual int Id { get; set; }
    }
public class Car : Base1
    {//same properties as defined above in above Car class + below property
        private int _carId;
        public int CarId
        {
            get { return _carId; }
            set { _carId = value; Id = value; }
        }
    }

            var car = new Car();
            car.Model = "Amaze";
            car.Year = new DateTime(2016, 1, 1);
            car.Features = new List<string> { "Light", "1", "2" };
            car.CarId = 1;

公共接口的可扩展性
{
int Id{get;set;}
}
公共类Base1:通用性
{
公共虚拟整数Id{get;set;}
}
公车:Base1
{//与上面的汽车类+下面的属性中定义的属性相同
私人国际加勒比;
公共国际加勒比
{
获取{return\u carId;}
设置{u carId=value;Id=value;}
}
}
var car=新车();
car.Model=“Amaze”;
车年=新日期时间(2016年1月1日);
car.Features=新列表{“Light”,“1”,“2”};
car.CarId=1;
在这里,基类的Id始终为零,派生的Id始终设置为非零值。 是否可以编写自定义转换器(通过检查属性Id的值是否为零,然后不进一步序列化该属性(Car1属性)?)
有什么建议,如何做到这一点

您遇到此问题的原因有两个:

return _car != null ? _car : new Car();
如果
\u car
的值为
null
,则每次都返回一个新实例,这会将序列化程序发送到无限遍历中,导致溢出

你需要重新考虑你的设计。您应该将新实例分配给内部变量,否则将丢失引用并继续使用
null

public Car Car1
{
    get
    {
        if(_car == null)
            _car = new Car();
        return _car;
    }
    set
    {
        _car = value;
    }
}

但是,这种自动初始化仍然是一个问题,因为总是有一个值要序列化。如果不存在对象,则该值应为
null
,这将允许序列化程序执行其工作并到达对象图的末尾。

可能是输入错误,但在上面使用的代码中,设置变量具有循环处理标志。我相信这就是你想要的。换句话说,尝试更改为:var serialize=JsonConvert.SerializeObject(car,settings);所以你的车有一辆车,那辆车有一辆车,那辆车有一辆车,那。。。你确定你的班级做了你想让它做的事吗?是的。我知道问题在哪里。但是很难重新思考这个设计并使其正确。这就是为什么我问是否有任何方法可以让它工作。@Gopu_Tunas:想一想。这就是序列化程序所做的,因为属性总是有一个值。如果序列化程序在某个点停止,您将丢失信息。否则它将永远消失:(伪代码)
Serialize(car)=>SerializeInternalProperty(car);=>属性(汽车);=>属性(汽车);=>属性(汽车);=>不动产(汽车);。。。永恒
。你到底要如何“修复”这个问题?@Gopu_Tunas我不知道你为什么会想要你正在创建的报废汽车场景,但是如果你愿意为序列化程序设置MaxDepth设置,你可以让序列化程序工作。@peter.edwards:正如我提到的,他会丢失信息,并在一开始就挫败了连载的目的,但你是对的。@Gopu_Tunas:你误解了连载。请再读一遍我的答案。您的修改版本仍然存在相同的问题,因为您正在尝试选择性地序列化内容。你需要重新考虑你的设计。序列化是对象图的一种表示形式,因此有选择地将自定义序列化程序中的内容省略是没有意义的。整个想法是,您希望能够具体化回完全相同的对象(图)。
public Car Car1
{
    get
    {
        if(_car == null)
            _car = new Car();
        return _car;
    }
    set
    {
        _car = value;
    }
}