我在通过DataContract序列化和反序列化单例时遇到了问题。
首先是一些事实:
1.) Singleton is "internal"
2.) Singleton contains Dictionaries我的序列化和反序列化工作得很好,但这不是单例的正确方式。如果我反序列化xml,我总是生成一个单例的新实例,并覆盖单例对象的当前引用-但此后它就不再是单例了。
有谁知道吗?-谢谢。
发布于 2012-07-24 22:52:55
查看msdn中的这个link,这里有一个序列化单例的例子。反序列化后,您应该返回引用,而不是对象。
发布于 2012-07-24 23:46:49
尝试使用NetDataContractSerializer-
NetDataContractSerializer与DataContractSerializer的一个重要区别在于: NetDataContractSerializer在序列化后的
中包含CLR类型信息,而DataContractSerializer则不包含。因此,只有当序列化和反序列化端共享相同的NetDataContractSerializer类型时,才能使用CLR。
序列化程序可以序列化已应用DataContractAttribute或SerializableAttribute属性的类型。它还序列化实现ISerializable的类型。
代码示例:
[DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
class Person : IExtensibleDataObject
{
[DataMember()]
public string FirstName;
[DataMember]
public string LastName;
[DataMember()]
public int ID;
public Person(string newfName, string newLName, int newID)
{
FirstName = newfName;
LastName = newLName;
ID = newID;
}
private ExtensionDataObject extensionData_Value;
public ExtensionDataObject ExtensionData
{
get { return extensionData_Value; }
set { extensionData_Value = value; }
}
}本地化:
Person p1 = new Person("Zighetti", "Barbara", 101);
FileStream fs = new FileStream(fileName, FileMode.Create);
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs);
NetDataContractSerializer ser = new NetDataContractSerializer();
ser.WriteObject(writer, p1);Msdn Link here
发布于 2012-12-21 00:54:18
( .net 4.0的代码)
我遇到了同样的问题:反序列化需要创建单例类的一个新实例,它可以(!)这样做是因为它在一个成员函数中:构造函数对成员是可见的,但该实例不能替换从外部可见的单例实例( "this")。
因此,您必须将属性从反序列化实例复制到"this“实例中。
手工复制很快就过时了,所以这里是我的解决方案,使用反射复制未标记为xmlignore的公共可写成员
public static class SerializationHelpers
{
/// <summary>
/// Copy all public props and fields that are not xmlignore
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="target"></param>
/// <param name="other"></param>
public static void CopyTypeFields<T>(T target, T other)
{
// get all public static properties of MyClass type
PropertyInfo[] propertyInfos = other.GetType().GetProperties(BindingFlags.Public
| BindingFlags.Instance);
FieldInfo[] fis = other.GetType().GetFields(BindingFlags.Public |
BindingFlags.Instance);
foreach (FieldInfo fi in fis)
{
if ((fi.Attributes & FieldAttributes.FieldAccessMask) !=
FieldAttributes.Literal &&
(fi.Attributes & FieldAttributes.FieldAccessMask) !=
FieldAttributes.Static)
{
if (IsXmlIgnored(fi)) { continue; }
var myval = fi.GetValue(other);
fi.SetValue(target, myval);
}
}
foreach (PropertyInfo pi in propertyInfos)
{
if (!pi.CanWrite || !pi.CanRead) { continue; }
if (IsXmlIgnored(pi)) { continue; }
var myval = pi.GetValue(other, null);
pi.SetValue(target, myval, null);
}
}
private static bool IsXmlIgnored(MemberInfo pi)
{
object[] fiGetCustomAttributes = pi.GetCustomAttributes(false);
foreach (object ob in fiGetCustomAttributes)
{
if (ob.GetType().
Equals(typeof(System.Xml.Serialization.XmlIgnoreAttribute)))
{
return true;
}
}
return false;
}
}
// to use it ...
// the deserialization method of the singleton mySingleton
public bool loadSingleton()
{
bool ret= false;
try
{
Type myType = GetType();
XmlSerializer reader = new XmlSerializer(myType);
try
{
using (StreamReader file = new StreamReader(filename))
{
try
{
mySingleton t1 = (mySingleton)reader.Deserialize(file);
CopySerializationFields(t1);
ret= true;
}
catch
{
...
}
}
}
catch
{
...
}
}
catch (Exception ex)
{
...
}
return ret;
}
private void CopySerializationFields(ProcessingSettings other)
{
SerializationHelpers.CopyTypeFields(this, other);
}https://stackoverflow.com/questions/11633326
复制相似问题