我从数据库读取了一个很长的json字符串,但是我只需要其中的一个属性。
我有两个选择: a. 为该json创建一个接口,并将其反序列化为该接口。(由于我只需要一个属性,这是否有点过度设计?) b. 查找我需要的子字符串(使用正则表达式?)
哪个更好呢?
更新:我正在使用 .net 3.5
JObject
等)进行反序列化,然后按名称请求所需的值?这样足够动态,不需要为每个内容创建一个接口,但比使用正则表达式要更加灵活。JObject json = JObject.Parse(text);
JToken value = json["foo"]["bar"];
我相信JSON.NET在.NET 4中也支持dynamic
,但是这里没有特别需要使用它。
正则表达式绝对不能参与讨论。就好像它从来不存在一样,请忘掉它。
创建并使用强类型是一个好习惯,也可能是我会采用的方式。
但如果你愿意,也可以使用dynamic
:
class Program
{
static void Main()
{
var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }";
var serializer = new JavaScriptSerializer();
dynamic value = serializer.DeserializeObject(json);
Console.WriteLine(value["foo"]["baz"][1]);
}
}
在控制台上打印2
。
dynamic
功能,无需使用正则表达式(对于这种情况不应该使用正则表达式),类似于您想要的方式。 这里描述了 http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx。
唯一的缺点是你无法保证对象的确切结构。yourDynamicObject.blah
更加灵活。你可以做:
var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""});
查找子字符串是一种危险的优化。
与 JSON 反序列化相比,值得优化这个过程吗?进行这样的查找是否安全?我们无法回答“是”,因为它大多取决于上下文。但我感觉应该说“不”,因为这显然会带来麻烦:即使现在可以工作,当您对象的结构或内容发生变化时,它可能会在未来出现问题。
虽然这是一个旧的帖子,但是在.NET 3.5中还有另一种方法:您可以将DeserializeObject返回的对象转换为Dictionary<String,Object>。 这与使用.NET 4.0动态关键字的解决方案有些相似:
JavaScriptSerializer serializer = new JavaScriptSerializer();
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }");
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj;
Console.WriteLine(ret["name"].GetType().Name); // Output: String
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32
Console.WriteLine(ret["age"].ToString()); // Output: 31
祝好
这要看情况而定。
选项A是更严格、有纪律和正式的方式。但是,就像你所说的,这可能过于繁琐了。那个JSON文件有多大?从长远来看,选项A留下了未来可能需要使用多个属性的潜在可能性。
选项B肯定更不正式和直接了当。它今天肯定有效,但将来可能需要不同的解决方案。
因此,也许您想将整个过程包装在一个方法中,以隐藏调用客户端的实现。返回只填充了单个属性的自定义对象。然后,如果将来需要,您可以更改该方法以利用完全倾斜的反序列化。
注意:我认为在C# 3.5中无法将反序列化为匿名类型。