gpt4 book ai didi

当两个类具有相同名称的属性时,.NET XmlSerializer 错误

转载 作者:行者123 更新时间:2023-12-02 02:56:20 27 4
gpt4 key购买 nike

准备好你们的火把吧!互联网上有人暗示 .NET 框架存在错误! :-)

考虑这个人为的模型:

public class Barn
{
public Horse Horse { get; set; }
public Motorcycle Motorcycle { get; set; }
}

public class Horse
{
public Horse()
{
Rider = "Jim Craig";
}

[XmlElement(IsNullable = true, Namespace = "abc")]
public string Rider { get; set; }
}

public class Motorcycle
{
public Motorcycle()
{
Rider = "Ghost";
}

[XmlElement(IsNullable = false, Namespace = "abc")]
public string Rider { get; set; }
}

请注意,两个 Rider 属性共享相同的名称和命名空间,但在其他方面不相关。一个是 XML 可为空的,另一个则不是。

下面是一些用于 XML 序列化然后反序列化空骑马者的代码:

// Create a Barn, with a Horse, with a null Rider
Barn barnBefore = new Barn();
barnBefore.Horse = new Horse();
barnBefore.Horse.Rider = null;

// Serialize and then deserialize the Barn
XmlSerializer serializer = new XmlSerializer(typeof(Barn));
MemoryStream stream = new MemoryStream();
serializer.Serialize(stream, barnBefore);
stream.Seek(0, SeekOrigin.Begin);
Barn barnAfter = (Barn)serializer.Deserialize(stream);

// Is the Horse's Rider still null?
Console.WriteLine(barnAfter.Horse.Rider == null ? "null" : "not null");

HorseRider 属性具有 IsNullable = true,因此应通过序列化维护其 null 值。运行上面的代码,输出确实是null。到目前为止一切顺利。

现在,有趣的部分是:交换 Barn 类中 HorseMotorcycle 属性的顺序,以便 摩托车是第一位的。

再次运行它,现在输出是not null。到底是什么?!

我已经在 VS 2008 和 2010 上进行了测试。

为了获得更多乐趣,请尝试将两个 Rider 属性设置为不同类型,例如一个为 string,另一个为 int。这确实搞砸了XmlSerializer

我对如何解决此问题不感兴趣。那是微不足道的。我的问题是:这是一个错误,还是我误解了什么?

最佳答案

嗯,在第一种情况下,编写的 XML 看起来有点像这样:

<Barn>
<Horse>
<Rider xsi:nil="true" xmlns="abc" />
</Horse>
</Barn>

但是在第二种情况下,XML 如下所示:

<Barn>
<Horse />
</Barn>

因此,在第二种情况下,反序列化过程中发生的事情基本上是这样的:

Barn barn = new Barn();
barn.Hose = new Horse();

因此,因为我们在构造函数中默认设置 Rider,所以它保留为“Jim Craig”。

有趣的是,只需更改 Barn 中元素的顺序即可反转该行为。为了尝试发现更多信息,我们可以使用 ILSpy 进行一些挖掘。和 Sgen.exe - 只需针对我们的程序集运行 sgen 并查看生成的程序集。

我们发现,在第一种情况下,Write2_HorseWrite3_Motorcycle 方法both中生成的代码有一行如下所示:

base.WriteNullableStringLiteral("Rider", "abc", o.Rider);

但是在第二种情况下,它看起来像这样:

base.WriteElementString("Rider", "abc", o.Rider);

我看不出为什么像这样改变元素的顺序会改变 HorseMotorcycle 元素的序列化行为,简而言之,在我看来,这就像 XML 序列化程序集生成器中的一个错误。

您应该向 Microsoft 报告此问题:-)

关于当两个类具有相同名称的属性时,.NET XmlSerializer 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5658624/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com