{"id":36021,"date":"2007-11-05T16:34:27","date_gmt":"2007-11-05T16:34:27","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/andrewarnottms\/2007\/11\/05\/workaround-for-xmlserializer-t-and-listt-bug\/"},"modified":"2019-04-03T22:28:45","modified_gmt":"2019-04-04T05:28:45","slug":"workaround-for-xmlserializer-t-and-listt-bug","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/workaround-for-xmlserializer-t-and-listt-bug\/","title":{"rendered":"Workaround for XmlSerializer T[] and List bug"},"content":{"rendered":"<p>The XmlSerializer in NetCF 2.0 has a bug where if a single serialization requires reflecting into types that use a mixture of Collection&lt;T&gt;-like types for the same T the XmlSerializer will throw an exception.&#xA0; Here an example where CF 2.0 would crash:<\/p>\n<p>  <!-- code formatted by http:\/\/manoli.net\/csharpformat\/ --> <\/p>\n<pre class=\"csharpcode\">\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> SerializingType1 {\r\n   <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span>[] FirstNames;\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; PhoneNumbers;\r\n}<\/pre>\n<p>This type would fail to serialize under NetCF 2.0 because T = string would appear in two kinds of collections.  This next example would also fail if you were serializing TypeA, because it contains a TypeB instance which has the another kind of T collection.<\/p>\n<p><!-- code formatted by http:\/\/manoli.net\/csharpformat\/ --><\/p>\n<pre class=\"csharpcode\">\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> TypeA {\r\n   <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span>[] FirstNames;\r\n   <span class=\"kwrd\">public<\/span> TypeB b;\r\n}\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> TypeB {\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; PhoneNumbers;\r\n}<\/pre>\n<p>If you can change the public API to use all T[] or List&lt;T&gt; and avoid the mixture, you&#8217;ve worked around the problem. So this would be the simplest workaround:<\/p>\n<p><!-- code formatted by http:\/\/manoli.net\/csharpformat\/ --><\/p>\n<pre class=\"csharpcode\">\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> SerializingType1 {\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; FirstNames;\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; PhoneNumbers;\r\n}<\/pre>\n<p>If you can&#8217;t change the public API to maintain compatibility for your customers, here&#8217;s another workaround that will eliminate the mixture for the XmlSerializer but keep the mixture for your customers.<\/p>\n<p><!-- code formatted by http:\/\/manoli.net\/csharpformat\/ --><\/p>\n<pre class=\"csharpcode\">\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> SerializingType1 {\r\n   [XmlIgnore]\r\n   <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span>[] FirstNames {\r\n      get { <span class=\"kwrd\">return<\/span> firstNamesHiddenList != <span class=\"kwrd\">null<\/span> ? firstNamesHiddenList.ToArray() : <span class=\"kwrd\">null<\/span>; }\r\n      set { firstNamesHiddenList = <span class=\"kwrd\">value<\/span> != <span class=\"kwrd\">null<\/span> ? <span class=\"kwrd\">new<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt;(<span class=\"kwrd\">value<\/span>) : <span class=\"kwrd\">null<\/span>; }\r\n   }\r\n   [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\r\n   [XmlArray(<span class=\"str\">\"FirstNames\"<\/span>)]\r\n   [Obsolete(<span class=\"str\">\"This member is for internal use only.\"<\/span>)]\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; firstNamesHiddenList;\r\n   <span class=\"kwrd\">public<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; PhoneNumbers;\r\n}<\/pre>\n<p>This will make the XmlSerializer work, and the API to the customer appear to be the same, except for a public member that they should never use directly that is only there (and public) because the XmlSerializer requires it.&#xA0; EditorBrowsableAttribute and ObsoleteAttribute are there to help the customer to not run into that member and use it when you didn&#x2019;t intend them to.&#xA0; <\/p>\n<p>This bug is fixed in .NET Compact Framework 3.5.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The XmlSerializer in NetCF 2.0 has a bug where if a single serialization requires reflecting into types that use a mixture of Collection&lt;T&gt;-like types for the same T the XmlSerializer will throw an exception.&#xA0; Here an example where CF 2.0 would crash: public class SerializingType1 { public string[] FirstNames; public List&lt;string&gt; PhoneNumbers; } This type [&hellip;]<\/p>\n","protected":false},"author":2685,"featured_media":37840,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[106,4617,3917,3918],"class_list":["post-36021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-permierdev","tag-net","tag-andarno","tag-mobile-devices","tag-netcf"],"acf":[],"blog_post_summary":"<p>The XmlSerializer in NetCF 2.0 has a bug where if a single serialization requires reflecting into types that use a mixture of Collection&lt;T&gt;-like types for the same T the XmlSerializer will throw an exception.&#xA0; Here an example where CF 2.0 would crash: public class SerializingType1 { public string[] FirstNames; public List&lt;string&gt; PhoneNumbers; } This type [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/2685"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=36021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36021\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/37840"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=36021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=36021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=36021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}