Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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# 反序列化JSON时如何将ObjectCreationHandling.Replace应用于选定属性?_C#_Json_Serialization_Json.net - Fatal编程技术网

C# 反序列化JSON时如何将ObjectCreationHandling.Replace应用于选定属性?

C# 反序列化JSON时如何将ObjectCreationHandling.Replace应用于选定属性?,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有一个类,它包含一个List属性,其默认构造函数分配列表并用一些默认值填充列表,例如: public class Configuration { public List<Tuple<int, int, int>> MyThreeTuple { get; set; } public Configuration() { MyThreeTuple = new List<Tuple<int, int, int>>

我有一个类,它包含一个
List
属性,其默认构造函数分配列表并用一些默认值填充列表,例如:

public class Configuration
{
    public List<Tuple<int, int, int>> MyThreeTuple { get; set; }

    public Configuration()
    {
        MyThreeTuple = new List<Tuple<int, int, int>>();
        MyThreeTuple.Add(new Tuple<int, int, int>(-100, 20, 501));
        MyThreeTuple.Add(new Tuple<int, int, int>(100, 20, 864));
        MyThreeTuple.Add(new Tuple<int, int, int>(500, 20, 1286));
    }
}

如何应用
对象创建处理。有选择地替换对象图中的某些属性,而不是其他属性?

您有几种方法可以强制替换列表,而不是重复使用列表:

  • 您可以向列表属性中添加,以指示应替换而不是重复使用该属性:

    public class Configuration
    {
        [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
        public List<Tuple<int, int, int>> MyThreeTuple { get; set; }
    }
    
    然后将其与以下内容一起使用:

  • 如果希望替换而不是重复使用所有列表属性,可以进行自定义,以执行以下操作:

    public class ListReplacementContractResolver : DefaultContractResolver
    {
        // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
        // http://www.newtonsoft.com/json/help/html/ContractResolver.htm
        // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
        // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
        static readonly ListReplacementContractResolver instance;
    
        // Using a static constructor enables fairly lazy initialization.  http://csharpindepth.com/Articles/General/Singleton.aspx
        static ListReplacementContractResolver() { instance = new ListReplacementContractResolver(); }
    
        public static ListReplacementContractResolver Instance { get { return instance; } }
    
        protected ListReplacementContractResolver() : base() { }
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var jsonProperty = base.CreateProperty(member, memberSerialization);
            if (jsonProperty.ObjectCreationHandling == null && jsonProperty.PropertyType.GetListType() != null)
                jsonProperty.ObjectCreationHandling = ObjectCreationHandling.Replace;
            return jsonProperty;
        }
    }
    
    public static class TypeExtensions
    {
        public static Type GetListType(this Type type)
        {
            while (type != null)
            {
                if (type.IsGenericType)
                {
                    var genType = type.GetGenericTypeDefinition();
                    if (genType == typeof(List<>))
                        return type.GetGenericArguments()[0];
                }
                type = type.BaseType;
            }
            return null;
        }
    }
    
  • 如果集合是get only(本例中不是),请参阅


  • 您有几种替代方法可以强制替换列表,而不是重复使用:

  • 您可以向列表属性中添加,以指示应替换而不是重复使用该属性:

    public class Configuration
    {
        [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
        public List<Tuple<int, int, int>> MyThreeTuple { get; set; }
    }
    
    然后将其与以下内容一起使用:

  • 如果希望替换而不是重复使用所有列表属性,可以进行自定义,以执行以下操作:

    public class ListReplacementContractResolver : DefaultContractResolver
    {
        // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
        // http://www.newtonsoft.com/json/help/html/ContractResolver.htm
        // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
        // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
        static readonly ListReplacementContractResolver instance;
    
        // Using a static constructor enables fairly lazy initialization.  http://csharpindepth.com/Articles/General/Singleton.aspx
        static ListReplacementContractResolver() { instance = new ListReplacementContractResolver(); }
    
        public static ListReplacementContractResolver Instance { get { return instance; } }
    
        protected ListReplacementContractResolver() : base() { }
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var jsonProperty = base.CreateProperty(member, memberSerialization);
            if (jsonProperty.ObjectCreationHandling == null && jsonProperty.PropertyType.GetListType() != null)
                jsonProperty.ObjectCreationHandling = ObjectCreationHandling.Replace;
            return jsonProperty;
        }
    }
    
    public static class TypeExtensions
    {
        public static Type GetListType(this Type type)
        {
            while (type != null)
            {
                if (type.IsGenericType)
                {
                    var genType = type.GetGenericTypeDefinition();
                    if (genType == typeof(List<>))
                        return type.GetGenericArguments()[0];
                }
                type = type.BaseType;
            }
            return null;
        }
    }
    
  • 如果集合是get only(本例中不是),请参阅


  • 请发表你的问题,这将极大地帮助我们帮助你。dbc,这是我所见过的最漂亮的编辑。请发表你的问题,这将极大地帮助我们帮助你。dbc,这是我所见过的最漂亮的编辑。太棒了!谢谢@dbc,这正是我需要的。我的问题是System.Net.Mail.MailAddress,因此添加属性从来都不是一个选项。我选择了解决方案4,一个定制的合同解析程序。再次感谢!明亮的谢谢@dbc,这正是我需要的。我的问题是System.Net.Mail.MailAddress,因此添加属性从来都不是一个选项。我选择了解决方案4,一个定制的合同解析程序。再次感谢!
    public class ConfigurationConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(Configuration).IsAssignableFrom(objectType);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var config = (existingValue as Configuration ?? (Configuration)serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());
            if (config.MyThreeTuple != null)
                config.MyThreeTuple.Clear();
            serializer.Populate(reader, config);
            return config;
        }
    
        public override bool CanWrite { get { return false; } }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new ConfigurationConverter() } };
    
    public class ListReplacementContractResolver : DefaultContractResolver
    {
        // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
        // http://www.newtonsoft.com/json/help/html/ContractResolver.htm
        // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
        // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
        static readonly ListReplacementContractResolver instance;
    
        // Using a static constructor enables fairly lazy initialization.  http://csharpindepth.com/Articles/General/Singleton.aspx
        static ListReplacementContractResolver() { instance = new ListReplacementContractResolver(); }
    
        public static ListReplacementContractResolver Instance { get { return instance; } }
    
        protected ListReplacementContractResolver() : base() { }
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var jsonProperty = base.CreateProperty(member, memberSerialization);
            if (jsonProperty.ObjectCreationHandling == null && jsonProperty.PropertyType.GetListType() != null)
                jsonProperty.ObjectCreationHandling = ObjectCreationHandling.Replace;
            return jsonProperty;
        }
    }
    
    public static class TypeExtensions
    {
        public static Type GetListType(this Type type)
        {
            while (type != null)
            {
                if (type.IsGenericType)
                {
                    var genType = type.GetGenericTypeDefinition();
                    if (genType == typeof(List<>))
                        return type.GetGenericArguments()[0];
                }
                type = type.BaseType;
            }
            return null;
        }
    }
    
    var settings = new JsonSerializerSettings { ContractResolver = ListReplacementContractResolver.Instance };