更新时间:2023-01-17 22:33:55
假设Values
是List<MyObject>
,而您的MyObject
类如下所示:
Assuming Values
is a List<MyObject>
and your MyObject
class looks like this:
class MyObject
{
public string Time { get; set; }
public int Level { get; set; }
}
您可以将所有代码替换为以下代码,以获得所需的结果:
you can replace all that code with the following to get the result you want:
string json = File.ReadAllText(fileName);
Values = JToken.Parse(json)["docs"].ToObject<List<MyObject>>();
之所以可行,是因为Json.Net默认情况下会忽略缺少的属性.由于MyObject
类不包含要反序列化为的_id
属性,因此您无需跳过试图将其从JSON中删除的箍.
This works because Json.Net will ignore missing properties by default. Since the MyObject
class does not contain an _id
property to deserialize into, you don't need to jump through hoops trying to remove it from the JSON.
Remove()
无效的原因的说明
Explanation of why Remove()
didn't work
JToken.Remove()
从其父级中删除JToken
.从其父JObject
中删除JProperty
或从JArray
中删除子JToken
是合法的.但是,您不能从JProperty
中删除该值. JProperty
必须始终仅具有一个值.
JToken.Remove()
removes a JToken
from its parent. It is legal to remove a JProperty
from its parent JObject
, or to remove a child JToken
from a JArray
. However, you cannot remove the value from a JProperty
. A JProperty
must always have exactly one value.
当您要求token["_id"]
时,您会得到称为_id
的JProperty
的值,而不是JProperty
本身.因此,如果您尝试在该值上调用Remove()
,则会收到错误消息.要使其按照您的方式工作,您需要像这样使用Parent
:
When you ask for token["_id"]
you get back the value of the JProperty
called _id
, not the JProperty
itself. Therefore you will get an error if you try to call Remove()
on that value. To make it work the way you are doing, you'd need to use Parent
like this:
if (inner["_id"] != null)
inner["_id"].Parent.Remove();
这说:找到名称为_id
的属性并给我值.如果存在,请获取该值的父级(该属性),并将其从其父级(包含JObject
)中删除."
This says "Find the property whose name is _id
and give me the value. If it exists, get that value's parent (the property), and remove it from its parent (the containing JObject
)."
一种更直接的方法是使用Property()
方法直接访问该属性.但是,此方法仅在JObject
上可用,而在JToken
上不可用,因此您需要将inner
的声明更改为JObject
或将其强制转换:
A more straightforward way to do it is to use the Property()
method to access the property directly. However, this method is only available on JObject
, not JToken
, so you would either need to change the declaration of inner
to a JObject
or cast it:
foreach (JObject inner in token["docs"].Children<JObject>())
{
JProperty idProp = inner.Property("_id");
if (idProp != null)
idProp.Remove();
...
}
最后,如注释中所述,如果您使用的是C#6或更高版本,则可以使用空条件运算符将代码缩短一点:
Lastly, as mentioned in the comments, if you're using C# 6 or later you can shorten the code a bit using the null-conditional operator:
inner.Property("_id")?.Remove();