C# C DataContract和序列化只读布尔字段始终为“true”
下面的类是一个人为的例子。我想用最简单的方法在每次序列化“isVisible”字段时将其序列化为“true”…不管它设置为什么 在实际代码中…这是一个更大的对象,并且有几个不同的构造函数,这些构造函数是从不同的点调用的 现在,我可以想出两种方法 创建一个“onserialization”方法,该方法在序列化期间使用反射将属性设置为“true”。我不确定这会不会奏效,但看起来会的 在启动类序列化的方法中…在序列化之前,创建isVisible为“true”的所有新项C# C DataContract和序列化只读布尔字段始终为“true”,c#,serialization,datacontractserializer,C#,Serialization,Datacontractserializer,下面的类是一个人为的例子。我想用最简单的方法在每次序列化“isVisible”字段时将其序列化为“true”…不管它设置为什么 在实际代码中…这是一个更大的对象,并且有几个不同的构造函数,这些构造函数是从不同的点调用的 现在,我可以想出两种方法 创建一个“onserialization”方法,该方法在序列化期间使用反射将属性设置为“true”。我不确定这会不会奏效,但看起来会的 在启动类序列化的方法中…在序列化之前,创建isVisible为“true”的所有新项 [DataContract] p
[DataContract]
public class MapItem
{
public MapItem(bool isVisible)
{
this.isVisible = isVisible;
}
[DataMember]
private readonly bool isVisible;
public bool IsVisible => isVisible;
}
为什么我需要这个?基本上,我需要加载这些项目,并使它们在加载后始终可见。运行应用程序时…MapItems可能会变为可见/不可见。因此,我希望XML始终为true,或者我希望MapItem中的值仅在反序列化时为true。您希望字段private readonly bool可见;在反序列化期间初始化为true。不幸的是,没有明显的、简单的方法来做到这一点
您提出的解决方案—在序列化过程中始终发出true,并利用数据协定序列化程序反序列化只读字段值的能力—不太理想,因为一个制作糟糕的XML文件(例如,其中的XML文件为false或甚至缺失)可能会在应用程序中引入意外行为
相反,考虑下列不需要序列化ISCVIEW值的替代方案:
修改只读字段的名称和语义,使默认值为正确的所需值。在这种情况下,您需要将当前isVisible替换为private readonly bool isNotVisible;: 使用反射设置回调中的字段值:[DataContract]
public class MapItem
{
public MapItem(bool isVisible)
{
this.isVisible = isVisible;
}
// Do not mark with [DataContract] as deserialized instances should always have the value
// set in the OnDeserializing() callback.
private readonly bool isVisible;
public bool IsVisible { get { return isVisible; } }
[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
typeof(MapItem)
.GetField(nameof(isVisible), BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(this, true);
}
}
最后,您可以按原样实现,并在流式构造函数中将isVisible初始化为true:
[Serializable]
public class MapItem : ISerializable
{
public MapItem(bool isVisible)
{
this.isVisible = isVisible;
}
private readonly bool isVisible;
public bool IsVisible { get { return isVisible; } }
#region ISerializable Members
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
#endregion
protected MapItem(SerializationInfo info, StreamingContext context)
{
this.isVisible = true;
}
}
但是,不建议这样做,因为现在需要手动序列化类的所有成员
我想用最简单的方法在每次序列化“isVisible”字段时将其序列化为“true”-您的意思是希望true出现在序列化的XML中,还是希望在序列化过程中将MapItem类中的实际字段值修改为true?如果您始终希望它为true,为什么选择它为false?你真的需要序列化它吗?您可以将其默认为true并忽略IgnoreDataMemberAttribute中的IsVisible吗?@dbc是的,我希望XML始终为true,或者我希望只有在反序列化时MapItem中的值才为true。基本上,我需要加载这些项目,并使它们在加载后始终可见。运行应用程序时…MapItems可能会变为可见/不可见。@TyCobb如上所述。运行应用程序时,这些项目可能可见或不可见。只有在加载时,我才需要将它们全部设置为可见。但是,我认为省时的方法是将它们保存为可见,而不是以这种方式加载它们。这里的基本问题是,您无法方便地将只读bool字段初始化为true。您愿意将字段的含义从isVisible转换为isNotVisible吗?在这种情况下,默认值将是正确的值。
[Serializable]
public class MapItem : ISerializable
{
public MapItem(bool isVisible)
{
this.isVisible = isVisible;
}
private readonly bool isVisible;
public bool IsVisible { get { return isVisible; } }
#region ISerializable Members
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
#endregion
protected MapItem(SerializationInfo info, StreamingContext context)
{
this.isVisible = true;
}
}