当使用泛型类型约束时,XmlSerializer抛出InvalidOperationException

时间:2010-03-02 07:45:13

标签: c# .net generics xmlserializer

当我尝试运行以下代码(两个独立的程序集)时

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));
    }
}

使用以下命令在Windows 7 64位中编译:

  

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

我遇到了这个例外:

  

System.InvalidOperationException:无法生成临时类   (结果= 1)。错误CS0012:类型   ITest在程序集中定义   没有引用。你必须添加一个   参考汇编ClassLibrary,   版本= 0.0.0.0,文化=中立,   PublicKeyToken = null hinzu。

     

在   System.Xml.Serialization.Compiler.Compile(大会   parent,String ns,   XmlSerializerCompilerParameters   xmlParameters,证据证据)
  在   System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping []   xmlMappings,Type [] types,String   defaultNamespace,证据证据,   XmlSerializerCompilerParameters   参数,装配装配,   Hashtable程序集)   System.Xml.Serialization.TempAssembly..ctor(XmlMapping []   xmlMappings,Type [] types,String   defaultNamespace,String location,   证据证据)   System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping   xmlMapping,Type type,String   defaultNamespace)at   System.Xml.Serialization.XmlSerializer..ctor(类型   type,String defaultNamespace)at   Program.Main(String [] args)

TestClass 删除其中T:ITest 或根本不使用泛型(例如使用 public void Test(ITest x))将防止异常被抛出,但我需要在我的实际应用程序中使用此构造。

有人理解为什么XmlSerializer无法处理where约束吗?

3 个答案:

答案 0 :(得分:6)

我认为你是out of luck。以下是Microsoft对此问题的回应:

  

感谢您提交此问题。   不幸的是,我们已经决定了   不会因为风险而得到解决   修复的重要性超过了它的好处。通过   下一次机会的时间   这种变化是出现的,希望是   那个新的序列化   未来版本的技术   Windows Communication Foundation   将解决您的方案。如果这   问题导致重大负面影响   业务影响,请联系   Microsoft产品支持服务。一世   很遗憾我们无法提供   更好的分辨率请放心   我们认真考虑过这个问题 - 一个   不会修复决定从来都不容易   使

这基本上说明你应该使用DataContractSerializer代替XmlSerializer或更改你的对象结构。

答案 1 :(得分:3)

实际上,你可能非常接近,甚至不知道。

尝试在ClassLibrary程序集中定义一个空的帮助器类,并将[Serializable, XmlInclude(SerializationReferenceHelper)]放在public class TestClass之上。

问题是Xml解析器不知道第二个类,因为它位于不同的程序集中,并且仅由代码中的where约束引用。是的,微软可能会写一些小曲目来查看所有已知的程序集......不确定它们为什么不这样做。但是现在这可能会奏效。

ClassLibrary

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));
    }
}

答案 2 :(得分:-3)

  

ITest类型定义为   未引用的程序集。 您   必须添加对程序集的引用   ClassLibrary

你做过这个吗?