我有一个包含水果列表的字符串。我的 C# 程序不能直接使用 Fruit,它需要将它们转换为 Banana 或 Apple。有关强制转换它们的信息包含在 json 的构造函数
属性中。
注意:我使用的是JSON.NET。
这是我想要达到的目标:
class Fruit{ public string constructor;}
class Banana : Fruit { public int monkey;}
class Apple : Fruit { public string shape;}
string json = @"[
{
""constructor"":""banana"",
""monkey"":1
},
{
""constructor"":""apple"",
""shape"":""round""
}]";
List<Fruit> fruitList = JsonConvert.DeserializeObject<List<Fruit>>(json);
List<Banana> bananaList = new List<Banana>();
List<Apple> appleList = new List<Apple>();
foreach(var fruit in fruitList){
if(fruit.constructor == "banana") bananaList.Add((Banana)fruit); //bug
if(fruit.constructor == "apple") appleList.Add((Apple)fruit); //bug
}
//use bananaList and appleList for stuff
但是,我不能进行强制转换。有什么方法可以让bananaList包含json中的所有对象,这些对象的构造函数属性设置为"banana"
并且与apple eList相同?
解决方案:
public static string objToJson(object obj) {
return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.Auto
});
}
public static T jsonToObj<T>(string str) {
return JsonConvert.DeserializeObject<T>(str, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.Auto
});
}
JSON.NET 只能解析它期望解析的内容。它无法假定它要使用的类的哪个多态子级。
如果可以控制源 JSON,则可以告诉序列化程序包含有关正在使用的类型的数据。
如果没有,我相信您需要手动读取数据(或通过JToken
s或类似方式),以找到构造函数
财产,然后再告诉它解析正确的类型。
您试图进行多态反序列化,但您要求反序列化程序将反序列化为水果列表。您不能向上转换到Apple/Banana,因为实例的类型是Fruit。
如果您可以控制json,则可以保存其中包含类型信息的json,并且反序列化器将自动创建正确的类型。
public class Fruit{ }
public class Banana : Fruit { public int monkey;}
public class Apple : Fruit { public string shape;}
class Program
{
static void Main(string[] args)
{
var list = new List<Fruit>(new Fruit[] {new Banana(), new Apple()});
var serializerSettings = new JsonSerializerSettings{ TypeNameHandling = TypeNameHandling.Auto };
var json = JsonConvert.SerializeObject(list, serializerSettings);
List<Fruit> fruitList = JsonConvert.DeserializeObject<List<Fruit>>(json, serializerSettings);
List<Banana> bananaList = new List<Banana>();
List<Apple> appleList = new List<Apple>();
foreach (var fruit in fruitList)
{
if (fruit is Banana) bananaList.Add((Banana) fruit);
if (fruit is Apple) appleList.Add((Apple) fruit);
}
}
}
你也可以使用一些linq来找到比foreach更容易的苹果/香蕉:
List<Banana> bananaList = fruitList.Where(f => f is Banana).Cast<Banana>().ToList();
List<Apple> appleList = fruitList.Where(f => f is Apple).Cast<Apple>().ToList();
或者,您可以使用此处讨论的转换器 使用 json.net 反序列化没有类型信息的多态 json 类
在JSON.Net中,有< code>$type可以用来指定要反序列化为哪种类型:
string json = @"[
{
""$type"":""Assembly.Namespace.banana"",
""monkey"":1
},
{
""$type"":""Assembly.Namespace.apple"",
""shape"":""round""
}]";
我创建了这样一个熊猫系列:
我正在尝试有一个通量通用转换器使用通用类型在Java 8。我把我的代码建立在这个答案的基础上。其思想基本上是实现这个特定的转换器->: 类型转换器->转换为我想要的任何类型。因此,我正在使用构造函数创建一个类型为的类,并返回一个方法。我想在调用上创建类似这样的多个条目:,但类类型不同。但它甚至对整数也不起作用。 当我使用此单元测试进行测试时,我得到错误:。
作为一个简化的例子,考虑这个有两个字段的表。一个是字符串,另一个是XML。 Source=“MediaConversions” 现在我想查询该表,并将结果作为json,但也要一次性将XML转换为json。 导致 [{"Source":"媒体转换","OrderParameter":" 但我想把它转换成: [{"Source":"MediaConversion","OrderParameter":{
我刚刚开始使用Retrofit2,我使用的API将所有有效的响应包装在一个“Response”对象中,如下所示。我需要告诉Retrofit只解析response中的值,而不实际将它们嵌套在另一个对象中。对于登录代码,我还面临着获取一个字符串的问题,我希望将其转换为实际的时间戳。 在上面仅有的两个实际值是: 我希望最终得到如下所示的东西。
我有两个实体,它们使用一个主键互相引用,主键是一个实体的整数。我不确定我做这件事的方式是否正确。 下面是引用主键id为int的实体 下面是我们从上面的实体中将外键设置为Kmichango kandaMchango的实体。 这里是表单的一部分,我在这里提交了用户在jumuiya_michango_form.html中提供的数据 下面是我的控制器中用于链接到表单和发布数据的两个方法 在我提交表单后,我
org.springframework.beans.ConversionNotSupportedException:未能将类型“java.lang.long”的属性值转换为属性“card”所需的类型“card”;嵌套异常是java.lang.IllegalStateException:无法将类型“java.lang.Long”的值转换为属性“Card”所需的类型“Card”:找不到匹配的编辑器或转
问题内容: 也许这很简单,但实际上我对Java 8功能不熟悉,不知道如何实现。我有一条包含以下文本的简单行: “密钥,名称” 并且我想将该行转换为String数组,并用逗号(,)分隔每个值,但是,我还想在返回最后一个数组之前修剪每个字段,所以我做了以下工作: 但是,这将返回Object []数组而不是String []数组。经过进一步检查,我可以确认内容实际上是String实例,但是数组本身是Ob
也许这很简单,但实际上我对Java8特性一无所知,不知道如何实现这一点。我有一个简单的行,包含以下文本: “密钥,名称”