- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在追踪一个错误,我注意到 Newtonsoft JSON 会将项目附加到 List<>
已在默认构造函数中初始化。我在 C# 聊天中做了更多挖掘并与一些人讨论,我们注意到此行为并不适用于所有其他集合类型。
https://dotnetfiddle.net/ikNyiT
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class TestClass
{
public Collection<string> Collection = new Collection<string>(new [] { "ABC", "DEF" });
public List<string> List = new List<string>(new [] { "ABC", "DEF" });
public ReadOnlyCollection<string> ReadOnlyCollection = new ReadOnlyCollection<string>(new [] { "ABC", "DEF" });
}
public class Program
{
public static void Main()
{
var serialized = @"{
Collection: [ 'Goodbye', 'AOL' ],
List: [ 'Goodbye', 'AOL' ],
ReadOnlyCollection: [ 'Goodbye', 'AOL' ]
}";
var testObj = JsonConvert.DeserializeObject<TestClass>(serialized);
Console.WriteLine("testObj.Collection: " + string.Join(",", testObj.Collection));
Console.WriteLine("testObj.List: " + string.Join(",", testObj.List));
Console.WriteLine("testObj.ReadOnlyCollection: " + string.Join(",", testObj.ReadOnlyCollection));
}
}
输出:
testObj.Collection: ABC,DEF
testObj.List: ABC,DEF,Goodbye,AOL
testObj.ReadOnlyCollection: Goodbye,AOL
如您所见Collection<>
属性不受反序列化的影响,List<>
附加到 ReadOnlyCollection<>
被替换。这是有意的行为吗?原因是什么?
最佳答案
它基本上归结为类型实例化和 ObjectCreationHandling
环境。 ObjectCreationHandling
Auto 0 Reuse existing objects, create new objects when needed.
Reuse 1 Only reuse existing objects.
Replace 2 Always create new objects.
默认为自动
( Line 44 )。
Auto 只有在确定当前类型是否有一个 TypeInitializer
为 null 的一系列检查后才会被覆盖。那时它检查是否有无参数构造函数。
///
/// Create a factory function that can be used to create instances of a JsonConverter described by the
/// argument type.
/// The returned function can then be used to either invoke the converter's default ctor, or any
/// parameterized constructors by way of an object array.
///
本质上它的行为是这样的(它看起来像是 6 个类中的大约 1500 行代码)。
ObjectCreationHandling och = ObjectCreationHandling.Auto;
if( typeInitializer == null )
{
if( parameterlessConstructor )
{
och = ObjectCreationHandling.Reuse;
}
else
{
och = ObjectCreationHandling.Replace;
}
}
此设置是 JsonSerializerSettings 的一部分,它由 DeserializeObject 的访问者模式构造函数内部组成。如上所示,每个设置都有不同的功能。
回到 List、Collection 和 ReadOnlyCollection,我们将查看每个的条件语句集。
列表
testObj.List.GetType().TypeInitializer == null
为假。结果,List
收到默认的 ObjectCreationHandling.Auto 并且在反序列化期间使用 testObj 实例的实例化 List,以及使用 serialized
字符串实例化的新 List .
testObj.List: ABC,DEF,Goodbye,AOL
收藏
testObj.Collection.GetType().TypeInitializer == null
为 true 表示没有可用的反射类型初始值设定项,因此我们转到下一个条件,即检查是否存在无参数构造函数. testObj.Collection.GetType().GetConstructor(Type.EmptyTypes) == null
为假。因此,Collection
接收到 ObjectCreationHandling.Reuse 的值(仅重用现有对象)。 Collection 的实例化实例是从 testObj 使用的,但是 serialized
字符串无法实例化。
testObj.Collection: ABC,DEF
只读集合
testObj.ReadOnlyCollection.GetType().TypeInitializer == null
为 true 表示没有可用的反射类型初始化程序,所以我们转到下一个条件,即检查是否有无参数构造函数. testObj.ReadOnlyCollection.GetType().GetConstructor(Type.EmptyTypes) == null
也是如此。因此 ReadOnlyCollection 收到 ObjectCreationHandling.Replace 的值(总是创建新对象)。仅使用 serialized
字符串中的实例化值。
testObj.ReadOnlyCollection: Goodbye,AOL
关于c# - 使用 Newtonsoft JSON 的 ObjectCreationHandling 的说明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27848547/
我在谷歌上花了很长时间,所以如果这是一个简单的修复请原谅我,但我找不到任何与 C# 中这个特定问题的修复相关的内容。 当尝试使用以下代码时,出现此错误: string obj = JsonConver
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 去年关闭。 Improve this
我正在尝试重新创建这个 json: { "request": { " TestRequest": { "OrderID": {
我正在测试我的 Web API。模拟数据我有这个: var objs = ((JArray)JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Head
目前正在尝试使用 fixer.io API 在 C# 中创建货币转换。 我在从 Twitter API 解析 JSON 时使用了与下面类似的方法,并且没有任何问题,我不完全确定这里发生了什么。 API
我正在尝试建立 Mike Jansen 的 JIRA REST Client ,我正在尝试提取 JIRA 版本信息。我是 JSON 的新手,所以我不确定这只是格式问题还是什么。 调试时,我有以下标记:
我正在尝试使用 将对象动态序列化到即时窗口中 Newtonsoft.Json.JsonConvert.SerializeObject(myObj); 但是我得到以下错误 The type 'Newto
我无法在 Visual Studio 2013 中构建解决方案。 这发生在我将我的 JSON.NET 包更新到 6.0.1 之后。在此之前,它就像一个魅力。 有什么想法吗? PS:这可能是关于 OWI
当有如下代码时 var TermSource = token.Value("annotations") .Values("Term Source") .FirstOrDefault
我需要将选中的复选框代码从 JavaScript 传递给 C#。我能够通过 JSON 发送代码。我的 JSON 值以 JArray 的形式出现。我在标题中得到了异常(exception)。 JSON:
注意:解决重定向问题后,我遇到了另一个问题,即出现错误“无法将 Newtonsoft.Json.Linq.JArray 转换为 Newtonsoft.Json.Linq.JToken”。因此,在我的回
我有以下简单的 POCO: public class ApiKey { public ApiKey(string key, string owner, List claims = nu
我查过这个问题,但我没有看到太多答案,显然没有一个有帮助,否则我不会问。我是 .NET 新手。 我的本地环境是Win7,Microsoft Virtual Web Developer 2010 Exp
好的-我已经将这个问题打了几个小时。是时候寻求帮助了。 我刚刚将Web应用程序项目升级到ASP.NET MVC 4 RC和新的WebApi。 我的Web api方法现在返回EMPTY json“{}”
我想忽略类中的某些属性,但出于多种原因我想保留类 POCO。因此我不想引入对 Json.NET 的依赖,也不想使用 JsonIgnoreAttribute。 有没有办法自定义契约(Contract)解
我正在尝试修复我编写的 WinForms 程序中的错误;我正在解析一个 JSON 字符串,然后将一些结果放入各种变量中。 有时,JSON 的特定元素不存在(出于真正的原因),因此我尝试使用以下代码来处
我只是尝试使用 C# 中的 Newtonsoft JSON 库将文件中的一些 JSON 反序列化为对象列表。以下是 MeetingFile.txt 文件的内容: [ { "People":
这是一个非常奇怪的错误发生。我有这些对象: public class Mobile_SettingModels { public string Token { get; set; }
我粘贴了 http://www.codeproject.com/Tips/789481/Bridging-the-Gap-between-Linqpad-and-Visual-Studio 中的代码进
这个问题在这里已经有了答案: Can I optionally turn off the JsonIgnore attribute at runtime? (3 个答案) 关闭 4 年前。 我目前正
我是一名优秀的程序员,十分优秀!