我们可以在使用 XmlSerializer 时将 Flag 枚举值标记为过时吗?
Posted
技术标签:
【中文标题】我们可以在使用 XmlSerializer 时将 Flag 枚举值标记为过时吗?【英文标题】:Can we mark a Flag enumeration value as obsolete when using XmlSerializer? 【发布时间】:2021-02-21 15:19:02 【问题描述】:我已经看到这个 [问题][1] 它指的是[Obsolete("...")]
,它听起来像是我可能需要使用的东西。但现在我认为我不能。
我有这个更新的标志枚举:
[Flags]
[Guid("xxxxx")]
[ComVisible(true)]
public enum AssignmentType
None = 0,
Attendant = 1,
ConductorCBS = 2,
ReaderCBS = 4,
Chairman = 8,
Mike = 16,
PlatformAttendant = 32,
Prayer = 64,
OCLM = 128,
Sound = 256,
Student = 512,
Custom = 1024,
Demonstration = 2048,
Assistant = 4096,
Host = 8192,
CoHost = 16384,
OCLMTreasures = 32768,
OCLMGems = 65536,
OCLMLiving = 131072
为了给你一些上下文,这些标志枚举出现在我的 XML 文件中,如下所示:
<Assignments Attendant="false" ConductorCBS="false" ReaderCBS="false" Chairman="false" Microphones="false" PlatformAttendant="false" Prayer="false" OCLM="false" Sound="false" Student="false" Assistant="false" Host="false" CoHost="false" OCLMTreasures="false" OCLMGems="true" OCLMLiving="false" Demonstrations="false">
相当简单的东西。现在,我为我的班级添加了一个升级方法:
public bool UpgradePublisherDatabase()
bool bSaveDB = false;
try
// Database should already be open
if(PublisherData.Version < 1)
// CODE SNIPPED
bSaveDB = true;
if(PublisherData.Version < 2)
// We need to upgrade the database
PublisherData.Version = 2;
var vPublisherKeys = new List<string>(PublisherData.PublisherDictionary.Keys);
foreach (string strPublisherKey in vPublisherKeys)
Publisher oPublisher = PublisherData.PublisherDictionary[strPublisherKey];
if (oPublisher.CanUseFor(AssignmentType.OCLM))
// We must set the other OCLM flags
oPublisher.SetCanUseFor(true, AssignmentType.OCLMTreasures);
oPublisher.SetCanUseFor(true, AssignmentType.OCLMGems);
oPublisher.SetCanUseFor(true, AssignmentType.OCLMLiving);
PublisherData.PublisherDictionary[strPublisherKey] = oPublisher;
bSaveDB = true;
if(bSaveDB)
return SavePublisherData();
catch (Exception ex)
SimpleLog.Log(ex);
return false;
return true;
在我的主应用程序 (Visual C++ MFC) 中,它调用我的 DLL 来加载 XML 文件。然后它对文件运行升级方法以使其保持最新状态。
此时,当 XML 文件为版本 2 时,我不再需要 XML 文件中的 AssignmentType.OCLM
标志,因为我不再使用它。但是在序列化时似乎不可能仅将标志枚举值标记为过时?
更新
这是该属性的定义:
[XmlAttribute("OCLM")]
public bool UseForOCLMAssignments
get => _Assignments.HasFlag(AssignmentType.OCLM); set
if (value)
_Assignments |= AssignmentType.OCLM;
else
_Assignments &= ~AssignmentType.OCLM;
所以,我希望能够将其读入,但我不想将其写出。那么在这里使用[Obsolete...]
语法是否可以接受?
[1]:Obsolete attribute causes property to be ignored by XmlSerialization
【问题讨论】:
serialize 方法只获取类中的内容并转换为 Xml。因此,如果有人在类中放置了一个过时的值,您希望序列化程序做什么?它确实应该在将数据添加到类的代码中修复。如果值已经存在于类中,我认为你想输出到 xml。 @jdweng 我的软件管理这个 XML 文件。在这个版本之前,我一直在使用那个标志。现在,继续前进,我正在使用三个新标志。但是我必须将枚举保留为有效条目,否则解析器不会崩溃吗?理想情况下,我只想删除该标志,然后当我读入 XML 时,如果它发现这个“未知”OCLM 属性,它会将其他三个属性设置为真。但我不知道XmlSerializer
是否可行。
您可以在类中创建自定义get/set,然后在get/set中添加代码。请参阅以下内容:docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
@jdweng 我真的不明白。我已经按照我向你展示的那样定义了我的对象。
【参考方案1】:
最后,这就是我所需要的:
[Obsolete("Use the OCLMTreasures, OCLMGems and OCLMLiving flag values instead.")]
[XmlAttribute("OCLM")]
public bool UseForOCLMAssignments
get => _Assignments.HasFlag(AssignmentType.OCLM); set
if (value)
_Assignments |= AssignmentType.OCLM;
else
_Assignments &= ~AssignmentType.OCLM;
所以Obsolete
关键字毕竟是要走的路。
【讨论】:
以上是关于我们可以在使用 XmlSerializer 时将 Flag 枚举值标记为过时吗?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 c# xmlserializer 反序列化以前序列化的 XML
如何使用 .NET XmlSerializer 使值类型可以为空?
在C#中 如何序列化图片 用System.Xml.Serialization.XmlSerializer这个可以吗?如果可以的话怎样使用?
XmlSerializer(Type type, Type[] extraTypes) 内存泄漏