ObjectManager 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
注意
Formatter-based serialization is obsolete and should not be used.
在对象进行反序列化时对其进行跟踪。
public ref class ObjectManager
public class ObjectManager
[System.Obsolete("Formatter-based serialization is obsolete and should not be used.", DiagnosticId="SYSLIB0050", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public class ObjectManager
[System.Runtime.InteropServices.ComVisible(true)]
public class ObjectManager
type ObjectManager = class
[<System.Obsolete("Formatter-based serialization is obsolete and should not be used.", DiagnosticId="SYSLIB0050", UrlFormat="https://aka.ms/dotnet-warnings/{0}")>]
type ObjectManager = class
[<System.Runtime.InteropServices.ComVisible(true)>]
type ObjectManager = class
Public Class ObjectManager
- 继承
-
ObjectManager
- 属性
示例
下面的代码示例演示如何使用 ObjectManager 类遍历对象图,仅遍历每个对象一次。
using System;
using System.Text;
using System.Collections;
using System.Runtime.Serialization;
using System.Reflection;
// This class walks through all the objects once in an object graph.
public sealed class ObjectWalker : IEnumerable, IEnumerator {
private Object m_current;
// This stack contains the set of objects that will be enumerated.
private Stack m_toWalk = new Stack();
// The ObjectIDGenerator ensures that each object is enumerated just once.
private ObjectIDGenerator m_idGen = new ObjectIDGenerator();
// Construct an ObjectWalker passing the root of the object graph.
public ObjectWalker(Object root) {
Schedule(root);
}
// Return an enumerator so this class can be used with foreach.
public IEnumerator GetEnumerator() {
return this;
}
// Resetting the enumerator is not supported.
public void Reset() {
throw new NotSupportedException("Resetting the enumerator is not supported.");
}
// Return the enumeration's current object.
public Object Current { get { return m_current; } }
// Walk the reference of the passed-in object.
private void Schedule(Object toSchedule) {
if (toSchedule == null) return;
// Ask the ObjectIDManager if this object has been examined before.
Boolean firstOccurrence;
m_idGen.GetId(toSchedule, out firstOccurrence);
// If this object has been examined before, do not look at it again just return.
if (!firstOccurrence) return;
if (toSchedule.GetType().IsArray) {
// The object is an array, schedule each element of the array to be looked at.
foreach (Object item in ((Array)toSchedule)) Schedule(item);
} else {
// The object is not an array, schedule this object to be looked at.
m_toWalk.Push(toSchedule);
}
}
// Advance to the next item in the enumeration.
public Boolean MoveNext() {
// If there are no more items to enumerate, return false.
if (m_toWalk.Count == 0) return false;
// Check if the object is a terminal object (has no fields that refer to other objects).
if (!IsTerminalObject(m_current = m_toWalk.Pop())) {
// The object does have field, schedule the object's instance fields to be enumerated.
foreach (FieldInfo fi in m_current.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
Schedule(fi.GetValue(m_current));
}
}
return true;
}
// Returns true if the object has no data fields with information of interest.
private Boolean IsTerminalObject(Object data) {
Type t = data.GetType();
return t.IsPrimitive || t.IsEnum || t.IsPointer || data is String;
}
}
public sealed class App {
// Define some fields in the class to test the ObjectWalker.
public String name = "Fred";
public Int32 Age = 40;
static void Main() {
// Build an object graph using an array that refers to various objects.
Object[] data = new Object[] { "Jeff", 123, 555L, (Byte) 35, new App() };
// Construct an ObjectWalker and pass it the root of the object graph.
ObjectWalker ow = new ObjectWalker(data);
// Enumerate all of the objects in the graph and count the number of objects.
Int64 num = 0;
foreach (Object o in ow) {
// Display each object's type and value as a string.
Console.WriteLine("Object #{0}: Type={1}, Value's string={2}",
num++, o.GetType(), o.ToString());
}
}
}
// This code produces the following output.
//
// Object #0: Type=App, Value's string=App
// Object #1: Type=System.Int32, Value's string=40
// Object #2: Type=System.String, Value's string=Fred
// Object #3: Type=System.Byte, Value's string=35
// Object #4: Type=System.Int64, Value's string=555
// Object #5: Type=System.Int32, Value's string=123
// Object #6: Type=System.String, Value's string=Jeff
注解
在反序列化期间,查询 FormatterObjectManager ,以确定对序列化流中某个对象的引用是引用已反序列化的对象 (向后引用) ,还是指向尚未反序列化 (前向引用) 的对象。 如果序列化流中的引用是向前引用,则可以 Formatter 向 ObjectManager注册修复。 如果序列化流中的引用是向后引用, 将 Formatter 立即完成引用。 修复是指在对象反序列化过程中完成尚未完成的对象引用的过程。 反序列化所需的 对象后, ObjectManager 将完成引用。
ObjectManager遵循一组规定修复顺序的规则。 当反序列化对象树时,实现 ISerializable 或具有 ISerializationSurrogate 的所有对象都可能希望它们通过 SerializationInfo 传输的所有对象都可用。 但是,父对象不能假定在完全反序列化时,其所有子对象都将完全完成。 所有子对象都将存在,但并非所有孙对象都一定存在。 如果对象需要执行依赖于对其子对象执行代码的某些操作,它可以延迟这些操作,实现 IDeserializationCallback 接口,并且仅在此接口上回调代码时才执行代码。
构造函数
ObjectManager(ISurrogateSelector, StreamingContext) |
已过时.
初始化 ObjectManager 类的新实例。 |