C#如何使用标准值初始化包含列表<t>的对象

时间:2017-12-25 05:25:05

标签: c# json

此问题与this问题有关。我设法进一步,但我现在无法使用默认值初始化我的整个对象,以防止它在列表级别为空。这样做的目的是传递&#34; null&#34;我的SQL查询的值。最终我想要的是我的数据库中的一条记录将表达:此行已被记录,但相关值为&#34; null&#34;。

我尝试过Brian的小提琴,但似乎没有用标准值初始化整个模型。

期望:在对象初始化时,&#34; null&#34;如果有通过JSON反序列化的值,则应使用值然后覆盖。

这是我尝试过的。这些都不会产生预期的效果。我收到此错误:

  

Application_Error:System.ArgumentNullException:Value不能为null。

每次我尝试访问数据模型中的一个列表时。

namespace Project.MyJob
{
 public class JsonModel
 {
    public JsonModel()
    {
        Type_X type_x = new Type_X(); // This works fine.
        List<Actions> action = new List<Actions>(); // This is never visible 
        /*in my object either before I initialise JObject or after. So whatever 
        gets initialised here never makes it to my object. Only Type_X appears 
        to be working as expected. */
        action.Add(new Actions {number = "null", time = "null", station = 
        "null", unitState = "null"}) // This also does not prevent my 
        //JsonModel object from being null.
    }
    public string objectNumber { get; set; }
    public string objectFamily { get; set; }
    public string objectOrder { get; set; }
    public string location { get; set; }
    public string place { get; set; }
    public string inventionTime { get; set; }
    public string lastUpdate { get; set; }
    public string condition { get; set; }

    public Type_X Type_X { get; set; }
    public List<Actions> actions { get; set; }         
 }

 public class Actions
 {
    public Actions()
    {
      // None of this seems to play a role at inititialisation.
      count = "null";
      datetime = "null";
      place = "null";
      status = "null";
    }

    // public string count { get; set; } = "null"; should be the same as above 
      // but also does not do anything.
    public string count { get; set; }
    public string datetime { get; set; }
    public string place { get; set; }
    public string status { get; set; }
 }

 public class Type_X
 {  
    public Type_X
    {
      partA = "null"; // This works.
    }

    public string partA { get; set; }

    public string PartB { get; set; }

    public string partC { get; set; }

    public string partD { get; set; }

    public string partE { get; set; }
  }
}

这就是我现在根据Brian的答案初始化对象的方法。

JObject = JsonConvert.DeserializeObject< JsonModel >(json.ToString(), new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore});

当我尝试迭代动作&#39;内容,它(逻辑上)给我上面提到的空错误。

for (int i = 0, len = JObject.actions.Count(); i < len; i++)

我目前对构造函数初始化的理解:

  • 如果我定义count = "null";等值,则它们应出现在任何创建的新对象中。
  • 如果存在默认值,我还会期望具有默认值(例如ex。的计数)的项目的列表将是Count() 1而不是null。怎么可能呢?

2 个答案:

答案 0 :(得分:3)

这会让你摆脱束缚:

private List<Actions> _actions = new List<Actions>();
public List<Actions> actions { get => _actions; set => _actions = value ?? _actions; }

这导致尝试将操作设置为null以将其设置为之前的值,并且最初不是null,因此它永远不会是null

我并不完全确定我正确地阅读了你的问题,所以这里是partA的相同片段:

private string _partA = "null";
public string partA { get => _partA; set => _partA = value ?? _partA; }

答案 1 :(得分:0)

我发现在某些情况下,在模型上使用默认构造函数初始化通用列表会增加易用性。否则,在应用任何逻辑之前,您总是希望验证它们不是null(即使是像检查列表长度这样简单的事情)。特别是如果实体在用户代码之外被水合,即数据库,webapi等......

一种选择是将初始化分为两部分。第1部分是默认构造函数的基本初始化,第2部分是水合逻辑的其余部分:

JObject = new List&lt; YourModel&gt;();

...&lt;这里的反序列化代码&gt;

或者你可以在反序列化代码中执行此操作,但这会增加一些复杂性。遵循此方法将允许您清理其他区域中的代码,因为每次访问都不需要立即进行空检查。