11

I want to serialize a pretty ordinary class, but the catch is it's nested in a static class like this:

public static class StaticClass
{
    [Serializable]
    public class SomeType
    {
        ...
    }
}

This code:

StaticClass.SomeType obj = new StaticClass.SomeType();
XmlSerializer mySerializer = new XmlSerializer(typeof(obj));

Produces this error:

StaticClass.SomeType cannot be serialized. Static types cannot be used as parameters or return types.

That error seems completely irrelevant; StaticClass.SomeType is not a static type.

Is there a way around this? Am I wrong to think this error is dumb?

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • 6
    btw, `[Serializable]` doesn't add anything here - `XmlSerializer` doesn't use it. – Marc Gravell Dec 18 '10 at 19:55
  • 2
    It has already been reported on Connect: https://connect.microsoft.com/VisualStudio/feedback/details/523204/class-that-is-nested-in-static-class-cannot-be-xml-serialized – Thomas Levesque Dec 18 '10 at 19:59

3 Answers3

8

As a pragmatic workaround - don't mark the nesting type static:

public class ContainerClass
{
    private ContainerClass() { // hide the public ctor
        throw new InvalidOperationException("no you don't");
    }

    public class SomeType
    {
        ...
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • as a workaround to the XmlSerializer limitation, this is the most practical for me. thanks :) – tenfour Dec 18 '10 at 20:12
  • 1
    +1 simple and effective. If I was going to do this I'd also marked the class as sealed. Reminds me of the old .NET 1 days (sealed class and private constructor) – RichardOD Dec 18 '10 at 20:17
4

It's know limitation in XmlSerializer ()

And workaround is to use DataContractSerializer (DataContractAttribute + DataMemberAttribute)

var ser = new DataContractSerializer(typeof (StaticClass.SomeType));
var obj = new StaticClass.SomeType {Int = 2};
ser.WriteObject(stream, obj);

...

static class StaticClass
{
    [DataContract]
    public class SomeType
    {
        [DataMember]
        public int Int { get; set; }
    }
}

As you can see DataContractSerializer doesn't even require StaticClass to be public. One difference is that you should use WriteObject' andReadObject' instead Serialize and Deserialize

The Smallest
  • 5,713
  • 25
  • 38
1

Either make the class non nested or consider using the DataContractSerializer instead.

RichardOD
  • 28,883
  • 9
  • 61
  • 81