没有[DataMember]属性和使用[IgnoreDataMember]属性的区别

39

所以我一直在查看我们的代码库,发现一些我们的DTO使用了混合的[DataMember][IgnoreDataMember]属性。

过去,我们被告知如果不想将DTO序列化,则简单地不添加[DataMember]属性。然后我看到了另一个属性,并进行了一些挖掘,似乎这明确指出该属性不会被序列化。

现在我的问题是哪个更好?添加[IgnoreDataMember]还是什么都不添加。

我已经问过身边的人,似乎[IgnoreDataMember]是从所有内容都需要序列化并且你必须声明应该忽略什么(我相信在.Net 2中)的时代开始的。然后他们反过来将其改为必须明确说明什么应该被序列化。现在似乎两者都可以。

1个回答

68
我已经询问过了,似乎 [IgnoreDataMember] 是在一切都需要序列化并且你必须规定应忽略的内容时出现的(我相信是在 .Net 2 中)。之后它们进行了反转,变成了必须显式地声明哪些内容应该进行序列化。

实际上并不完全是这样;如果将其标记为[DataContract],则仅考虑标记为[DataMember]的成员;如果未标记为[DataContract],则默认为所有内容,但可以使用[IgnoreDataMember]来减少成员。 我通常只省略我不想序列化的内容中的[DataMember],但在许多方面[IgnoreDataMember]更加明确——主要是为了方便维护者。它表示“我故意不序列化这个”,而不是“也许我知道这个没有被序列化,但是我可能忘记添加属性”。 两者都可以工作。

3
根据微软公司的说法:"IgnoreDataMemberAttribute属性仅在与未标记的类型一起使用时才会被识别"。如果您在同一个类上同时使用[DataContract][IgnoreDataMember],则后者会被忽略。 - Michael Edenfield
2
@MichaelEdenfield 说得很严谨,DataContractSerializer 默认序列化所有公共字段和属性(公共字段非常罕见);即使如此,这还是有点模糊不清。例如,如果我们谈论的是 NetDataContractSerializer,那么它默认序列化所有字段(包括私有字段),但不包括属性。 - Marc Gravell
3
虽然这是一个旧帖子,但昨天我遇到了一个问题,表明Edenfield先生所说的并不完全正确。 我的一个类有一个字段和4个属性。这4个属性将某种形式的数据(例如字节数组、字符串或其他类型)转换并写入该字段。我使用了DataContract属性标记了这个类,并且只将字段标记为DataMember。然而,这种方式反序列化程序并没有忽略这些属性,而是将它们设置为默认值(这会覆盖字段)。在属性上添加[IgnoreDataMember]修饰符解决了这个问题。因此,属性并没有被忽略。 - Cedric Mamo
使用[DataContract]和[DataMember]的一个优点是变量/属性名称的解耦。在我的情况下,我有一个Java后端,约定变量以小写字母开头,这与C#中公共变量/属性以大写字符开头的约定相矛盾。 - Vering

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接