다음을 통해 공유


ObjectManager 클래스

개체가 deserialize될 때 추적합니다.

네임스페이스: System.Runtime.Serialization
어셈블리: mscorlib(mscorlib.dll)

구문

‘선언
<ComVisibleAttribute(True)> _
Public Class ObjectManager
‘사용 방법
Dim instance As ObjectManager
[ComVisibleAttribute(true)] 
public class ObjectManager
[ComVisibleAttribute(true)] 
public ref class ObjectManager
/** @attribute ComVisibleAttribute(true) */ 
public class ObjectManager
ComVisibleAttribute(true) 
public class ObjectManager

설명

deserialization 도중에 FormatterObjectManager를 쿼리하여 serialize된 스트림에 있는 개체에 대한 참조가 이미 deserialize된 개체를 참조하는지(후방 참조) 아니면 아직 deserialize되지 않은 개체를 참조하는지(전방 참조) 확인합니다. serialize된 스트림에 있는 참조가 전방 참조이면 FormatterObjectManager에 픽스업을 등록할 수 있으며, serialize된 스트림에 있는 참조가 후방 참조이면 Formatter는 이 참조를 곧바로 완료합니다. 픽스업 프로세스는 개체 deserialization 프로세스 중에 완료되지 않은 개체 참조를 종료하는 프로세스입니다. 필수 개체를 deserialize한 후에 ObjectManager는 참조를 완료합니다.

ObjectManager는 픽스업 순서를 지시하는 일련의 규칙을 따릅니다. ISerializable을 구현하거나 ISerializationSurrogate를 갖는 모든 개체는 개체 트리가 deserialize될 때 SerializationInfo를 통해 전송된 모든 개체를 사용할 수 있습니다. 그러나 부모 개체가 완전히 deserialize되는 경우 모든 자식 개체도 완전히 완료된다고 가정할 수는 없습니다. 자식 개체는 모두 존재하지만 모든 손자 개체가 반드시 존재하는 것은 아닙니다. 개체가 해당 자식 개체의 코드를 실행해야 하는 특정 작업을 수행해야 하는 경우 이 작업을 지연시키고 IDeserializationCallback 인터페이스를 구현한 다음 이 인터페이스에서 코드가 콜백되는 경우에만 코드를 실행하는 것이 가능합니다.

예제

다음 코드 예제에서는 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

상속 계층 구조

System.Object
  System.Runtime.Serialization.ObjectManager

스레드로부터의 안전성

이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.

플랫폼

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

참고 항목

참조

ObjectManager 멤버
System.Runtime.Serialization 네임스페이스