ISerializable派生クラス、FormatterServices.GetSerializableMembers()でC#

ISerializableを実装している派生クラスは、基底クラスがそれを持たないので、基底クラスとそれ自身のメンバーの両方を直列化できます。派生クラスでは、FormatterServices.GetSerializableMembers()を使用してベースクラスのメンバーを取得し、 MSDNに基づいてフィールドとプロパティの両方を返す必要があります。しかし、以下のコードでは、フィールドを返すだけです。

MSDN

internal static class ISerializableVersioning {
   public static void Go() {
      using (var stream = new MemoryStream()) {
         BinaryFormatter formatter = new BinaryFormatter();
         formatter.Serialize(stream, new Derived());
         stream.Position = 0;
         Derived d = (Derived)formatter.Deserialize(stream);
         Console.WriteLine(d);
      }
   }

   [Serializable]
   private class Base {
      protected String m_name = "base";
      protected String Name { get { return m_name; } set { m_name = value; } }
      public Base() { /* Make the type instantiable*/ }
   }

   [Serializable]
   private class Derived : Base, ISerializable {
      new private String m_name = "derived";
      public Derived() { /* Make the type instantiable*/ }

     //If this constructor didn't exist, we'd get a SerializationException
     //This constructor should be protected if this class were not sealed
      [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
      private Derived(SerializationInfo info, StreamingContext context) {
        //Get the set of serializable members for our class and base classes
         Type baseType = this.GetType().BaseType;
         MemberInfo[] mi = FormatterServices.GetSerializableMembers(baseType, context);

        //Deserialize the base class's fields from the info object
         for (Int32 i = 0; i < mi.Length; i++) {
           //Get the field and set it to the deserialized value
            FieldInfo fi = (FieldInfo)mi[i];
            fi.SetValue(this, info.GetValue(baseType.FullName + "+" + fi.Name, fi.FieldType));
         }

        //Deserialize the values that were serialized for this class
         m_name = info.GetString("Name");
      }

      [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
      public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
        //Serialize the desired values for this class
         info.AddValue("Name", m_name);

        //Get the set of serializable members for our class and base classes
         Type baseType = this.GetType().BaseType;

//**Should GetSerializableMembers return both the field and property? But it only return field here**
         MemberInfo[] mi = FormatterServices.GetSerializableMembers(baseType, context);

        //Serialize the base class's fields to the info object
         for (Int32 i = 0; i < mi.Length; i++) {
           //Prefix the field name with the fullname of the base type
             object value = ((FieldInfo) mi[i]).GetValue(this);
            info.AddValue(baseType.FullName + "+" + mi[i].Name, value);
         }
      }
      public override String ToString() {
         return String.Format("Base Name={0}, Derived Name={1}", base.Name, m_name);
      }
   }
}
1

1 答え

GetSerializableMembersはMemberInfo配列を返します。 EventInfo、MethodBase、またはPropertyInfoオブジェクトであっても、すべてをFieldInfoにキャストしています。

1
追加された
FieldInfo型の要素を1つだけ返します。
追加された 著者 Pingpong,