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

发布于 2024-08-23 06:17:49 字数 1659 浏览 5 评论 0原文

当我尝试

以下代码(两个独立的程序集) 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

I'我得到这个异常:

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

在 System.Xml.Serialization.Compiler.Compile(程序集 父级,字符串 ns, XmlSerializer编译器参数 xml参数,证据证据)
在 System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings、Type[] 类型、字符串 defaultNamespace,证据证据, XmlSerializer编译器参数 参数、装配装配、 哈希表组件)位于 System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings、Type[] 类型、字符串 默认命名空间、字符串位置、 证据证据)在 System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping、类型类型、字符串 默认命名空间)位于 System.Xml.Serialization.XmlSerializer..ctor(类型 类型,字符串默认命名空间)位于 Program.Main(String[] args)

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

有人理解为什么 XmlSerializer 无法处理 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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

御守 2024-08-30 06:17:49

我认为你是 运气不好。以下是微软对此问题的回应:

感谢您提交此问题。
不幸的是,我们决定
不会得到解决,因为风险
修复的效果超过了它的好处。经过
下一次机会的时间
这种变化的发生,希望是
新的序列化
未来版本中的技术
Windows 通信基金会
将解决您的情况。如果这个
问题正在造成重大负面影响
业务影响,请联系
微软产品支持服务。我
遗憾的是我们无法提供
更好的分辨率。请放心
我们认真考虑过这个问题——
不会轻易做出决定
制作。

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

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.

九命猫 2024-08-30 06:17:49

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

尝试在 ClassLibrary 程序集中定义一个空帮助器类,并将 [Serialized, 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));
    }
}

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.

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));
    }
}
岁月静好 2024-08-30 06:17:49

类型 ITest 定义在
未引用的程序集。
必须添加对程序集的引用
类库

你做到了吗?

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

Have you done this?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文