XmlSerializer throws an InvalidOperationException when using a generic type constraint, where

When I try to run the following code (two separated assemblies)

ClassLibrary.cs

public interface ITest { } 

Program.cs

 using System; public class TestClass { public void Test<T>(T x) where T : ITest { } } static class Program { static void Main(string[] args) { new System.Xml.Serialization.XmlSerializer(typeof(TestClass)); } } 

Compiled on a 64-bit version of Windows 7 using the following commands:

c: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ csc / target: library ClassLibrary.cs

c: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ csc / reference: ClassLibrary.dll Program.cs

I get this exception:

System.InvalidOperationException: Unable to create a temporary class (Result = 1). bug CS0012: type ITest is defined in an assembly that is not mentioned. You must add a reference to the assembly ClassLibrary, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null hinzu.

in System.Xml.Serialization.Compiler.Compile (Collection parent, String ns, XmlSerializerCompilerParameters xmlParameters, proof of evidence)
in System.Xml.Serialization.TempAssembly.GenerateAssembly (XmlMapping [] xmlMappings, Type [] types, String defaultNamespace, evidence evidence, XmlSerializerCompilerParameters parameters, assembly assemblies, Hashtable) in System.Xml.Serialization.TempAssembly..ctor (XmlMapping [] xmlMappings, Type [] types, String defaultNamespace, String location, Proof of evidence) in System.Xml.Serialization.XmlSerializer.GenerateTempAssembly (XmlMapping xmlMapping, Type type, String defaultNamespace) in System.Xml.Serialization.XmlSerializer..ctor (Type type , String defaultNamespace) in Program.Main (String [] args)

Removing where T: ITest from TestClass or doesn't use generic files at all (e.g. using public void Test (ITest x)) will prevent the exception from being thrown, but I need this construct in my real application.

Does anyone understand why the XmlSerializer cannot handle where the restriction is?

+7
generics c # xmlserializer
source share
3 answers

I think you are out of luck . Here is the answer from Microsoft about this problem:

Thanks for submitting this issue. Unfortunately, we decided that this would not be considered because the risk of correction outweighs its benefits. From the time of the next opportunity to make this change happen, the hope is that the new technology serialization in a future version of the Windows Communication Foundation will consider your scenario. If this problem causes a significant negative business impact, please contact Microsoft Product Support Services. I'm sorry that we could not provide a better resolution. Be sure that we seriously considered this issue - the decision will not be resolved to make.

This basically means that you should use the DataContractSerializer instead of the XmlSerializer or change the structure of the object.

+6
source share

Actually, you can be VERY close and not even know this.

Try defining an empty helper class inside your ClassLibrary assembly and place [Serializable, XmlInclude(SerializationReferenceHelper)] just above the public class TestClass .

The problem is that the Xml parser is not aware of the second class, because it is in a different assembly and only refers to the where clause in your code. Yes, Microsoft could write a little tune for viewing in all known assemblies ... I don’t know why they do not. But for now, this might work.

Classlibrary

 public class SerializationReferenceHelper { } public interface ITest { } 

Program

 [Serializable, XmlInclude(typeof(SerializationReferenceHelper))] public class TestClass { public void Test<T>(T x) where T : ITest { } } static class Program { static void Main(string[] args) { new System.Xml.Serialization.XmlSerializer(typeof(TestClass)); } } 
+3
source share

The type ITest is defined in an assembly that is not referenced. You must add a reference to the assembly ClassLibrary

You did it?

-3
source share

All Articles