ObjectManager 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
追蹤物件在去序列化過程中的狀態。
public ref class ObjectManager
public class ObjectManager
[System.Runtime.InteropServices.ComVisible(true)]
public class ObjectManager
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
備註
在反序列化過程中,查詢 Formatter 是 ObjectManager 為了判斷序列化串流中對物件的引用是指已反序列化的物件(向後參考),還是尚未被反序列化的物件(前向參考)。 如果序列化串流中的參考是前向參考,則Formatter可以註冊一個固定。ObjectManager 如果序列化串流中的參考是向後參考,則會 Formatter 立即完成該參考。 修正是指在物件反序列化過程中尚未完成的物件參考最終完成的過程。 當所需的物件被反序列化後,將 ObjectManager 完成引用。
這 ObjectManager 遵循一套規則來決定固定順序。 所有實作 ISerializable 或擁有 的 ISerializationSurrogate 物件,當物件樹被反序列化時,都可以預期它們所透過 SerializationInfo 的所有物件都能被使用。 然而,父物件不能假設所有子物件在完全反序列化後都會完全完成。 所有子物件都會存在,但不一定所有子物件都會存在。 如果物件需要執行依賴於子物件執行程式碼的某些動作,它可以延遲這些動作、實作介面 IDeserializationCallback ,並只在被呼叫回來時執行程式碼。
建構函式
| 名稱 | Description |
|---|---|
| ObjectManager(ISurrogateSelector, StreamingContext) |
初始化 ObjectManager 類別的新執行個體。 |