7

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

类库.cs

public interface ITest
{
}

程序.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、Version=0.0.0.0、Culture=neutral、PublicKeyToken=null hinzu 的引用。

在 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, System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence) 在 System.Xml.Serialization.XmlSerializer.GenerateTempAssembly 的 XmlSerializerCompilerParameters 参数、程序集程序集、哈希表程序集(XmlMapping xmlMapping, Type type, String defaultNamespace) at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace) at Program.Main(String[] args)

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

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

4

3 回答 3

6

我觉得你不走运。以下是微软对此问题的回应:

感谢您提交此问题。不幸的是,我们决定不解决它,因为修复的风险超过了它的好处。到下一次进行此更改的机会出现时,希望未来版本的 Windows Communication Foundation 中的新序列化技术能够解决您的方案。如果此问题对业务造成重大负面影响,请联系 Microsoft 产品支持服务。我很遗憾我们无法提供更好的解决方案。请放心,我们认真考虑了这个问题 - 不会轻易做出决定。

这基本上说您应该使用DataContractSerializer而不是XmlSerializer或更改您的对象结构。

于 2010-03-02T07:57:21.603 回答
3

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

尝试在您的 ClassLibrary 程序集中定义一个空的辅助类并放在[Serializable, XmlInclude(SerializationReferenceHelper)]上面public class TestClass

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

类库

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));
    }
}
于 2010-03-04T18:09:34.797 回答
-3

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

你做过吗?

于 2010-03-02T07:47:50.797 回答