我有一个标记为[Serializable]的类,其中包含System.Diagnostics.Stopwatch成员。但是由于System.Diagnostics.Stopwatch,我无法使用BinaryFormatter来序列化该类。有没有办法标记或使System.Diagnostics.Stopwatch可序列化?
最佳答案
您可以为StopWatch创建SerializationSurrogate和SurrogateSelector。
请注意,StopWatch类可能具有机器特定的状态,即滴答频率等。因此,在进行序列化时,请检查序列化上下文,以确保该序列化不适合跨计算机使用(如果要复制所有值),或者仅使用计时数据创建一个全新的实例。
namespace MaLio.StopWatch {
class Program {
static void Main(string[] args) {
Container container = new Container();
Container copy = null;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
// may be a formatter created elsewhere
if (formatter.SurrogateSelector == null) {
formatter.SurrogateSelector = new StopWatchSelector();
}
else {
formatter.SurrogateSelector.ChainSelector(new StopWatchSelector());
}
using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) {
formatter.Serialize(stream, container);
stream.Flush();
stream.Position = 0;
copy = formatter.Deserialize(stream) as Container;
}
System.Diagnostics.Debug.WriteLine(
"Reference Equals: " + (object.ReferenceEquals(container, copy)).ToString());
System.Console.ReadKey();
}
}
public class StopWatchSelector : System.Runtime.Serialization.SurrogateSelector {
private StopWatchSurrogate _Surrogate;
public StopWatchSelector() {
_Surrogate = new StopWatchSurrogate();
}
public override System.Runtime.Serialization.ISerializationSurrogate GetSurrogate(
System.Type type,
System.Runtime.Serialization.StreamingContext context,
out System.Runtime.Serialization.ISurrogateSelector selector) {
System.Runtime.Serialization.ISerializationSurrogate surrogate;
surrogate = base.GetSurrogate(type, context, out selector);
if (surrogate == null) {
if (type == typeof(System.Diagnostics.Stopwatch)) {
surrogate = _Surrogate;
}
}
return surrogate;
}
}
public class StopWatchSurrogate : System.Runtime.Serialization.ISerializationSurrogate {
private const string NULL_INDICATOR_STRING = @"__StopWatchNull";
// the invalid contexts as an example
private const System.Runtime.Serialization.StreamingContextStates INVALID_CONTEXTS =
System.Runtime.Serialization.StreamingContextStates.CrossMachine |
System.Runtime.Serialization.StreamingContextStates.Remoting;
public void GetObjectData(
object obj,
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) {
System.Diagnostics.Stopwatch stopWatch = obj as System.Diagnostics.Stopwatch;
if (stopWatch == null) {
info.AddValue(NULL_INDICATOR_STRING, true);
}
else {
info.AddValue(NULL_INDICATOR_STRING, false);
// add other values looked up via reflection
}
}
public object SetObjectData (
object obj,
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context,
System.Runtime.Serialization.ISurrogateSelector selector) {
System.Diagnostics.Stopwatch stopWatch = null;
bool isNull = info.GetBoolean(NULL_INDICATOR_STRING);
if (!isNull) {
stopWatch = obj as System.Diagnostics.Stopwatch;
// read other values and set via reflection
}
return stopWatch;
}
private void CheckContext(System.Runtime.Serialization.StreamingContext context) {
if ((context.State & INVALID_CONTEXTS) != 0) {
throw new System.NotSupportedException();
}
}
}
[System.Serializable]
public class Container {
private System.Diagnostics.Stopwatch _Watch = new System.Diagnostics.Stopwatch();
}
}
关于c# - 如何序列化System.Diagnostics.Stopwatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1866351/