无法在 C# 中序列化数组对象

Unable to Serialize array Object in C#

我有以下 class:

public partial class ct_ServiceProductInfoWireless {

    private object[] itemsField;
    private bool directFulfillmentField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("NewWirelessLines", typeof(ct_WirelessLines))]
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine", typeof(ct_ServiceProductInfoWirelessWirelessLine))]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

ct_WirelessLines Class

public partial class ct_WirelessLines {

    private ct_NewWirelessLine[] wirelessLineField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine")]
    public ct_NewWirelessLine[] WirelessLine {
        get {
            return this.wirelessLineField;
        }
        set {
            this.wirelessLineField = value;
        }
    }
}

问题是当我序列化我的 ct_ServiceProductInfoWireless 对象时出现以下异常:

The type ct_WirelessLines[] may not be used in this context.

这是序列化代码:

var stringWriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(objectToSerialize.GetType());
serializer.Serialize(stringWriter, objectToSerialize); //Getting exception here
return stringWriter.ToString();

怎么了?

ct_NewWirelessLine class

public partial class ct_NewWirelessLine {

    private ct_NewRatePlan ratePlanField;

    private ct_DataPlan dataPlanField;

    private ct_OrderDevice deviceField;

    private ct_PhoneNumber telephoneNumberField;

    private string lineNumberField;

    private bool isPrimaryLineField;
}

ct_ServiceProductInfoWireless无线线路class

public partial class ct_ServiceProductInfoWirelessWirelessLine {

    private ct_Device deviceField;

    private ct_RatePlan ratePlanField;

    private ct_InstallmentPlan installmentPlanField;

    private string paymentArrangementField;

    private ct_OptionalFeature[] optionalPackagesField;

    private ct_WirelessFeature[] optionalFeaturesField;

    private string lineNumberField;

    private string primarySQNumberField;

    private string secondarySQNumberField;

    private st_CustomerType customerTypeField;

    private bool customerTypeFieldSpecified;

    private string ppuZipField;

    private string wtnField;

    private bool directFulfillmentField;

    private bool directFulfillmentFieldSpecified;
}

我能够重现错误消息

System.InvalidOperationException: The type ct_WirelessLines[] may not be used in this context.

通过将 ct_ServiceProductInfoWireless.Items 指定为 ct_WirelessLines 数组的 数组而不是一维数组:

Items = new [] { new [] { new ct_WirelessLines() } }`

此代码可以编译,因为 Items 只是一个对象数组,但不会序列化,因为 XmlSerializer 只需要 XmlElementAttribute.Type attributes to be in the array, and not some nested array. Demo fiddle #1 here 中声明的两种类型的对象。

解决方案是不这样做并使用平面一维数组:

Items = new [] { new ct_WirelessLines() },

演示 fiddle #2 here.

如果您有两个集合,一个 ct_WirelessLines 和一个 ct_ServiceProductInfoWirelessWirelessLine,您可以通过将集合内容向上转换为 [=24] 将它们合并到最终的 Items 数组中=],然后使用 Concat() and ToArray():

var wirelessLines = GetWirelessLines(); // Some IEnumerable<ct_WirelessLines>
var productInfo = GetProductInfoWirelessWirelessLines(); // Some IEnumerable<ct_ServiceProductInfoWirelessWirelessLine>

var objectToSerialize = new ct_ServiceProductInfoWireless
{
    Items = wirelessLines.Cast<object>().Concat(productInfo).ToArray(),
};

演示 fiddle #3 here.

顺便说一句,看起来这段代码是由xsd.exe自动生成的。此工具通常不会自动为选择元素序列生成 class 层次结构。但是,如果您可以手动修改生成的代码,则可以为 Items 引入一个抽象基 class,这将防止您在编译时遇到的那种错误:

public partial class ct_ServiceProductInfoWireless 
{
    private WirelessItemBase[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("NewWirelessLines", typeof(ct_WirelessLines))]
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine", typeof(ct_ServiceProductInfoWirelessWirelessLine))]
    public WirelessItemBase[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

public abstract class WirelessItemBase
{
}

public partial class ct_WirelessLines : WirelessItemBase
{
}

public partial class ct_ServiceProductInfoWirelessWirelessLine : WirelessItemBase
{
}

现在以下甚至无法编译:

Items = new [] { new [] { new ct_WirelessLines() } }, //Compilation error (line 72, col 13): Cannot implicitly convert type 'ct_WirelessLines[][]' to 'WirelessItemBase[]'

演示 fiddle #4 here.