Bha*_*kar 39 c# singleton serialization
如果我们序列化静态类会发生什么?如果我们序列化它,可以创建多个静态类的实例吗?
[Serializable]
public static class MyClass
{
public static MyClass()
{
}
public static bool IsTrue()
{
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
假设我将对象XmlSerialize为XML文件,稍后我反序列化回一个对象.另一个副本存在于内存中(当somone第一次直观地表达静态calss时创建).请问,有两个副本的对象?如果是的话,我们可以阻止吗?它是否适用于遵循单例模式的任何类?
Jon*_*eet 55
从来没有静态类的任何实例:它们都是抽象的并且在IL中是密封的,因此CLR将阻止创建任何实例.因此没有什么可序列化的.静态字段永远不会被序列化,这是静态类可以拥有的唯一状态.
关于XML序列化的问题毫无意义,因为没有人能够创建静态类的实例.
Mik*_*nov 14
您可以创建以下类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Soap;
using System.Reflection;
using System.IO;
namespace SerializeStatic_NET
{
public class SerializeStatic
{
public static bool Save(Type static_class, string filename)
{
try
{
FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public);
object[,] a = new object[fields.Length,2];
int i = 0;
foreach (FieldInfo field in fields)
{
a[i, 0] = field.Name;
a[i, 1] = field.GetValue(null);
i++;
};
Stream f = File.Open(filename, FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(f, a);
f.Close();
return true;
}
catch
{
return false;
}
}
public static bool Load(Type static_class, string filename)
{
try
{
FieldInfo[] fields = static_class.GetFields(BindingFlags.Static | BindingFlags.Public);
object[,] a;
Stream f = File.Open(filename, FileMode.Open);
SoapFormatter formatter = new SoapFormatter();
a = formatter.Deserialize(f) as object[,];
f.Close();
if (a.GetLength(0) != fields.Length) return false;
int i = 0;
foreach (FieldInfo field in fields)
{
if (field.Name == (a[i, 0] as string))
{
field.SetValue(null, a[i,1]);
}
i++;
};
return true;
}
catch
{
return false;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您必须定义对System.Runtime.Serialization.Formatters.Soap的引用.
比如,在您的程序中,您要保存以下静态类:
public static class A
{
public static string s;
public static int i;
public static double z;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下代码:
bool ok = SerializeStatic.Save(typeof(A), "c:\\tests\\a.dat");
Run Code Online (Sandbox Code Playgroud)
如果要加载保存的数据(在同一程序或其他程序中),请使用以下代码:
bool ok2 = SerializeStatic.Load(typeof(A), "c:\\tests\\a.dat");
Run Code Online (Sandbox Code Playgroud)
字段As,Ai,Az将获得新的加载值.
为什么不使用一个临时实例类作为静态类的镜像?
[XmlRoot]
public class SerializeClass
{
public int Number {
get;
set;
}
}
public static class SerializedClass {
public static int Number {
get;
set;
}
public static void Serialize(Stream stream) {
SerializeClass obj = new SerializeClass();
obj.Number = Number;
XmlSerializer serializer = new XmlSerializer(typeof(SerializeClass));
serializer.Serialize(stream, obj);
}
public static void Deserialize(Stream stream) {
XmlSerializer serializer = new XmlSerializer(typeof(SerializeClass));
SerializeClass obj = (SerializeClass)serializer.Deserialize(stream);
Number = obj.Number;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道它有点像黑客,但它实现了相同的目的,同时在运行时仍允许重构,并在运行时进行值验证.
| 归档时间: |
|
| 查看次数: |
33169 次 |
| 最近记录: |