When I try to run the following code (two separated assemblies)
public interface ITest
{
}
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 in Windows 7 64-Bit 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'm getting the this exception:
System.InvalidOperationException: Unable to generate a temporary class (result=1). error CS0012: The type ITest is defined in an assembly that is not referenced. You must add a reference to assembly ClassLibrary, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null hinzu.
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence) at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace) at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace) at Program.Main(String[] args)
Removing the where T : ITest from TestClass or not using generics 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.
Do anybody understand why the XmlSerializer is unable to handle the where constraint?
I think you are out of luck. Here's the response from Microsoft about this issue:
Thank you for submitting this issue. Unfortunately, we have decided that it will not be addressed because the risk of the fix outweighs its benefit. By the time the next opportunity to make this change comes about, the hope is that the new serialization technologies in a future version of the Windows Communication Foundation will address your scenario. If this issue is causing significant negative business impact, please contact Microsoft Product Support Services. I regret that we could not provide a better resolution. Rest assured that we seriously considered this issue - a Won't Fix decision is never easy to make.
This basically says the you should use DataContractSerializer instead of XmlSerializer or change your object structure.
Actually, you may be VERY close, and not even know it.
Try to define an empty helper class inside your ClassLibrary assembly and put [Serializable, XmlInclude(SerializationReferenceHelper)]
just above public class TestClass
.
The issue is that the Xml parser doesn't know about the second class because it is in a different assembly and is only referenced by the where constraint in your code. Yes, Microsoft could write a little ditty to look in all of the known assemblies... not sure why they don't. But for now this might work.
public class SerializationReferenceHelper { }
public interface ITest { }
[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));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With