GVKun编程网logo

在列表中使用不同类型去解组JSON(在列表中,不同数据项用______分隔)

21

在本文中,我们将详细介绍在列表中使用不同类型去解组JSON的各个方面,并为您提供关于在列表中,不同数据项用______分隔的相关解答,同时,我们也将为您带来关于c#–使用不同类的通用列表XML序列化、

在本文中,我们将详细介绍在列表中使用不同类型去解组JSON的各个方面,并为您提供关于在列表中,不同数据项用______分隔的相关解答,同时,我们也将为您带来关于c# – 使用不同类的通用列表XML序列化、c# – 在一个列表中有更多不同类型的对象、c# – 在列表中使用两个单独的字符串类型、c# – 如何在列表中找到具有一个不同值的相同类的有用知识。

本文目录一览:

在列表中使用不同类型去解组JSON(在列表中,不同数据项用______分隔)

在列表中使用不同类型去解组JSON(在列表中,不同数据项用______分隔)

我在解组JSON结构时遇到了麻烦:

{  "id": 10,  "result": [    {      "bundled": true,      "type": "RM-J1100"    },    [      {        "name": "PowerOff",        "value": "AAAAAQAAAAEAAAAvAw=="      },      {        "name": "Input",        "value": "AAAAAQAAAAEAAAAlAw=="      }    ]  ]}

我实际上需要结果中的第二个切片项。

我目前的尝试是

type Codes struct {    Id     int32      `json:"id"`    Result []interface{} `json:"result"`}type ResultList struct {    Info  InfoMap    Codes []Code}type InfoMap struct {    Bundled bool   `json:"bundled"`    Type    string `json:"type"`}type Code struct {    Name  string `json:"name"`    Value string `json:"value"`}

输出是这样的:

{10 {{false } []}}

但是我也尝试使用这个:

type Codes struct {    Id     int32      `json:"id"`    Result []interface{} `json:"result"`}

输出正常:

{10 [map[type:RM-J1100 bundled:true] [map[name:PowerOff value:AAAAAQAAAAEAAAAvAw==] map[name:Input value:AAAAAQAAAAEAAAAlAw==]]]}

我还可以引用Result [1]索引:

[map[name:PowerOff value:AAAAAQAAAAEAAAAvAw==] map[name:Input value:AAAAAQAAAAEAAAAlAw==]]

但是我无法将接口类型转换为任何其他匹配类型。谁能告诉我如何进行界面转换。哪种方法才是“最佳”。

答案1

小编典典

一种选择是将顶级事物解组为json.RawMessage最初的一部分。

然后遍历成员,并查看每个成员的第一个字符。如果它是一个对象,则将其解组到您的InfoMap标头结构中;如果它是一个数组,则将其解组到该Code结构的一个切片中。

或者,如果可以预测的话,只需将第一个成员解组为一个结构,将第二个成员解构为切片。

我在操场上举了这种方法的例子。

type Response struct {    ID        int               `json:"id"`    RawResult []json.RawMessage `json:"result"`    Header    *Header           `json:"-"`    Values    []*Value          `json:"-"`}type Header struct {    Bundled bool   `json:"bundled"`    Type    string `json:"type"`}type Value struct {    Name  string `json:"name"`    Value string `json:"value"`}func main() {    //error checks ommitted    resp := &Response{}    json.Unmarshal(rawJ, resp)    resp.Header = &Header{}    json.Unmarshal(resp.RawResult[0], resp.Header)    resp.Values = []*Value{}    json.Unmarshal(resp.RawResult[1], &resp.Values)}

c# – 使用不同类的通用列表XML序列化

c# – 使用不同类的通用列表XML序列化

我有以下代码:

BaseContent.cs

public class BaseContent
{
   // Some auto properties
}

News.cs

public class News : BaseContent
{
   // Some more auto properties
}

Events.cs

public class Event : BaseContent
{
   // Some more auto properites
}

GenericResponse.cs

public class GenericResponse<T> 
{
  [XmlArray("Content")]
  [XmlArrayItem("NewsObject",typeof(News)]
  [XmlArrayItem("EventObject",typeof(Event)]
  public List<T> ContentItems { get; set; }
}

NewsResponse.cs

public class NewsResponse : GenericResponse<News> {}

EventResponse.cs

public class EventResponse : GenericResponse<Event> {}

你可以看到,我有一个基类BaseContent和从它派生的两个类.接下来我有一个通用响应类,因为xml文件的结构总是相同的,但是在某些属性中它们有所不同.

我以为我可以用[XmlArrayItem]指定用于特定类的名称.但是现在我得到错误:

system.invalidOperationException: Unable to generate a temporary class (result=1).
error CS0012: The type ‘System.Object’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Runtime,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a’.

我无法添加此引用,因为我正在使用Windows 8应用程序.

如果我注释掉其中一个[XmlArrayItem],它的工作效果很好.

任何人都有一个想法来解决这个问题?

更新
我不能使用DataContractSerializer,因为我必须使用XmlAttributes

解决方法

编辑:随意下载 demo project

您没有提供对象的所有属性,所以允许我添加一些 – 就像一个例子:

public class BaseContent
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
}

[XmlType(TypeName = "EventObject")]
public class Event : BaseContent
{
    [XmlAttribute("EventId")]
    public int EventId { get; set; }
}

[XmlType(TypeName = "NewsObject")]
public class News : BaseContent
{
    [XmlAttribute("NewsId")]
    public int NewsId { get; set; }
}

GenericResponse.cs可以这样定义 – 不需要为数组项指定typeof:

public class GenericResponse<T>
{
    [XmlArray("Content")]
    public List<T> ContentItems { get; set; }

    public GenericResponse()
    {
        this.ContentItems = new List<T>();
    }
}

然后你有响应类:

public class EventResponse : GenericResponse<Event>
{
}

public class NewsResponse : GenericResponse<News>
{
}

示例1:序列化EventResponse对象

var response = new EventResponse
{
    ContentItems = new List<Event> 
    {
        new Event {
            EventId = 1,Name = "Event 1"
        },new Event {
            EventId = 2,Name = "Event 2"
        }
    }
};

string xml = XmlSerializer<EventResponse>.Serialize(response);

输出XML:

<?xml version="1.0" encoding="utf-8"?>
<EventResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Content>
        <EventObject Name="Event 1" EventId="1" />
        <EventObject Name="Event 2" EventId="2" />
    </Content>
</EventResponse>

如果您尝试与NewsResponse相同,它将正常工作. BTW我使用我的generic XmlSerializer,点击链接了解更多.

XmlSerializer.cs:

/// <summary>
/// XML serializer helper class. Serializes and deserializes objects from/to XML
/// </summary>
/// <typeparam name="T">The type of the object to serialize/deserialize.
/// Must have a parameterless constructor and implement <see cref="Serializable"/></typeparam>
public class XmlSerializer<T> where T: class,new()
{
    /// <summary>
    /// Deserializes a XML string into an object
    /// Default encoding: <c>UTF8</c>
    /// </summary>
    /// <param name="xml">The XML string to deserialize</param>
    /// <returns>An object of type <c>T</c></returns>
    public static T Deserialize(string xml)
    {
        return Deserialize(xml,Encoding.UTF8,null);
    }

    /// <summary>
    /// Deserializes a XML string into an object
    /// Default encoding: <c>UTF8</c>
    /// </summary>
    /// <param name="xml">The XML string to deserialize</param>
    /// <param name="encoding">The encoding</param>
    /// <returns>An object of type <c>T</c></returns>
    public static T Deserialize(string xml,Encoding encoding)
    {
        return Deserialize(xml,encoding,null);
    }

    /// <summary>
    /// Deserializes a XML string into an object
    /// </summary>
    /// <param name="xml">The XML string to deserialize</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
    /// <returns>An object of type <c>T</c></returns>
    public static T Deserialize(string xml,XmlReaderSettings settings)
    {
        return Deserialize(xml,settings);
    }

    /// <summary>
    /// Deserializes a XML string into an object
    /// </summary>
    /// <param name="xml">The XML string to deserialize</param>
    /// <param name="encoding">The encoding</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
    /// <returns>An object of type <c>T</c></returns>
    public static T Deserialize(string xml,Encoding encoding,XmlReaderSettings settings)
    {
        if (string.IsNullOrEmpty(xml))
            throw new ArgumentException("XML cannot be null or empty","xml");

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

        using (MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(xml)))
        {
            using (XmlReader xmlReader = XmlReader.Create(memoryStream,settings))
            {
                return (T) xmlSerializer.Deserialize(xmlReader);
            }
        }
    }

    /// <summary>
    /// Deserializes a XML file.
    /// </summary>
    /// <param name="filename">The filename of the XML file to deserialize</param>
    /// <returns>An object of type <c>T</c></returns>
    public static T DeserializefromFile(string filename)
    {
        return DeserializefromFile(filename,new XmlReaderSettings());
    }

    /// <summary>
    /// Deserializes a XML file.
    /// </summary>
    /// <param name="filename">The filename of the XML file to deserialize</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
    /// <returns>An object of type <c>T</c></returns>
    public static T DeserializefromFile(string filename,XmlReaderSettings settings)
    {
        if (string.IsNullOrEmpty(filename))
            throw new ArgumentException("filename","XML filename cannot be null or empty");

        if (! File.Exists(filename))
            throw new FileNotFoundException("Cannot find XML file to deserialize",filename);

        // Create the stream writer with the specified encoding
        using (XmlReader reader = XmlReader.Create(filename,settings))
        {
            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
            return (T) xmlSerializer.Deserialize(reader);
        }
    }

    /// <summary>
    /// Serialize an object
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <returns>A XML string that represents the object to be serialized</returns>
    public static string Serialize(T source)
    {
        // indented XML by default
        return Serialize(source,null,GetIndentedSettings());
    }

    /// <summary>
    /// Serialize an object
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="namespaces">Namespaces to include in serialization</param>
    /// <returns>A XML string that represents the object to be serialized</returns>
    public static string Serialize(T source,XmlSerializerNamespaces namespaces)
    {
        // indented XML by default
        return Serialize(source,namespaces,GetIndentedSettings());
    }

    /// <summary>
    /// Serialize an object
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
    /// <returns>A XML string that represents the object to be serialized</returns>
    public static string Serialize(T source,XmlWriterSettings settings)
    {
        return Serialize(source,settings);
    }

    /// <summary>
    /// Serialize an object
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="namespaces">Namespaces to include in serialization</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
    /// <returns>A XML string that represents the object to be serialized</returns>
    public static string Serialize(T source,XmlSerializerNamespaces namespaces,XmlWriterSettings settings)
    {
        if (source == null)
            throw new ArgumentNullException("source","Object to serialize cannot be null");

        string xml = null;
        XmlSerializer serializer = new XmlSerializer(source.GetType());

        using (MemoryStream memoryStream = new MemoryStream())
        {
            using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream,settings))
            {
                System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
                x.Serialize(xmlWriter,source,namespaces);

                memoryStream.Position = 0; // rewind the stream before reading back.
                using (StreamReader sr = new StreamReader(memoryStream))
                {
                    xml = sr.ReadToEnd();
                } 
            }
        }

        return xml;
    }

    /// <summary>
    /// Serialize an object to a XML file
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="filename">The file to generate</param>
    public static void SerializetoFile(T source,string filename)
    {
        // indented XML by default
        SerializetoFile(source,filename,GetIndentedSettings());
    }

    /// <summary>
    /// Serialize an object to a XML file
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="filename">The file to generate</param>
    /// <param name="namespaces">Namespaces to include in serialization</param>
    public static void SerializetoFile(T source,string filename,XmlSerializerNamespaces namespaces)
    {
        // indented XML by default
        SerializetoFile(source,GetIndentedSettings());
    }

    /// <summary>
    /// Serialize an object to a XML file
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="filename">The file to generate</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
    public static void SerializetoFile(T source,XmlWriterSettings settings)
    {
         SerializetoFile(source,settings);
    }

    /// <summary>
    /// Serialize an object to a XML file
    /// </summary>
    /// <param name="source">The object to serialize</param>
    /// <param name="filename">The file to generate</param>
    /// <param name="namespaces">Namespaces to include in serialization</param>
    /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
    public static void SerializetoFile(T source,"Object to serialize cannot be null");

        XmlSerializer serializer = new XmlSerializer(source.GetType());

        using (XmlWriter xmlWriter = XmlWriter.Create(filename,settings))
        {
            System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
            x.Serialize(xmlWriter,namespaces);
        }
    }

    #region Private methods


    private static XmlWriterSettings GetIndentedSettings()
    {
        XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
        xmlWriterSettings.Indent = true;
        xmlWriterSettings.IndentChars = "\t";

        return xmlWriterSettings;
    }

    #endregion
}

c# – 在一个列表中有更多不同类型的对象

c# – 在一个列表中有更多不同类型的对象

是否可以在同一列表中添加更多不同类型的对象,我该如何做?

我有一个基类和三个子类,我希望所有子类对象在同一个列表中.

解决方法

当然 – 只需使用基类型作为泛型类型参数创建一个列表:

List<Control> controls = new List<Control>();
controls.Add(new TextBox());
controls.Add(new Label());
controls.Add(new Button());
// etc

请注意,当您再次检索项目时,您只会“知道”它们作为基本类型,因此如果要执行任何特定于子类型的操作,则需要进行转换.例如:

// Assuming you kNow that there's at least one entry...
Control firstControl = controls[0];
TextBox tb = firstControl as TextBox;
if (tb != null)
{
    // Use tb here
}

如果要获取特定类型(或其子类型)的所有元素,可以使用OfType<>方法:

foreach (TextBox tb in controls.OfType<TextBox>())
{
    // Use tb here
}

c# – 在列表中使用两个单独的字符串类型

c# – 在列表中使用两个单独的字符串类型

好吧,对于我的C#编程课我正在制作冒险游戏.我想我明白如何做到这一点大多数期待我在设置“世界”时遇到麻烦.

我有一个世界级(World.cs),我开始为每个房间创建一个列表.但是我很困惑为每个房间添加名称和描述.

例如,如果List(房间)是String类型,我会做room.Add(“监狱”,“这是监狱).
做这个的最好方式是什么?

解决方法

那是你创建一个类的时候

public class Room {
   public string Name { get; set; }
   public string Description { get; set; }
}

并保留一份房间清单:

List<Room> rooms = new List<Room>();

要向列表中添加任何内容,只需执行以下操作:

rooms.Add(new Room { Name = "Prison",Description = "This is a prison" });

对象用于将数据组合在一起,这将允许更清晰的代码.它是面向对象编程的基石之一.

c# – 如何在列表中找到具有一个不同值的相同类

c# – 如何在列表中找到具有一个不同值的相同类

我有一份特权列表. Privilege类有四个属性:Type,Accesstype,Value和Action.
如果有多个权限,其中Type,Accesstype和Value相同,但我想要抛出异常,但操作是不同的.

因此,例如p1和p2的列表会抛出异常:

Privilege p1 = new Privilege{Type = "a",Accesstype = "a",Value = "a",Action = "a"};
Privilege p2 = new Privilege{Type = "a",Action = "b"};

我想使用LINQ,但不知道如何.

解决方法

所以你想允许重复类型访问类型值,但只有当操作也相同时?

bool throwException = pList
    .GroupBy(x => new { x.Type,x.Accesstype,x.Value })
    .Any(g => g.Select(p => p.Action).distinct().Count() > 1);

首先,我正在构建这三个属性的组.然后我检查这些组中是否包含多个动作.然后你可以抛出异常.

如果替换,可能会进行小的优化(如果重复列表很大)

distinct().Count() > 1

distinct().Skip(1).Any()

今天关于在列表中使用不同类型去解组JSON在列表中,不同数据项用______分隔的讲解已经结束,谢谢您的阅读,如果想了解更多关于c# – 使用不同类的通用列表XML序列化、c# – 在一个列表中有更多不同类型的对象、c# – 在列表中使用两个单独的字符串类型、c# – 如何在列表中找到具有一个不同值的相同类的相关知识,请在本站搜索。

本文标签: