泛型類序列化

iDotNetSpace發表於2009-10-26
  • 泛型類可以標記為可序列化,但只有當泛型型別引數可序列化時,泛型類才可序列化。如下:
        class One
        {
            
    public string Name { getset; }
        }
        [Serializable]
        
    class Program<T>
        {
            
    public T Name { getset; }
        }
        
    class Program
        {
            
    static void Main(string[] args)
            {
                Program
    <One> pro = new Program<One>();
                BinaryFormatter formatter 
    = new BinaryFormatter();
                Stream stream 
    = new MemoryStream();
                
    try
                {
                    formatter.Serialize(stream, pro);
                }
                
    catch (SerializationException ex)
                {
                    
    // 程式集“MyConsoleApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的類                 // 型“MyConsoleApplication.One”未標記為可序列化。
                    Console.WriteLine(ex.Message);
                }
                Console.ReadLine();
            }
        }

         為了使泛型類可以序列化,有以下幾種方法:

  1. 將泛型型別引數定義的成員變數標識為NonSerialized,這樣泛型型別引數的型別就不會影響到泛型類的序列化。
        class One
        {
            public string Name { get; set; }
        }
        [Serializable]
        
    class Program<T>
        {

            
    // T不會影響Program序列化,因為此成員變數被標識為不可序列化
            [NonSerialized]
            
    public T Name { getset; }
        }
       
        class
     Program
        {
            
    static void Main(string[] args)
            {

                Program<One> pro = new Program<One>();
                BinaryFormatter formatter = new BinaryFormatter();
                Stream stream 
    = new MemoryStream();
                formatter.Serialize(stream, pro);

                Console.ReadLine();
            }

        }
  2. 將泛型型別引數進行約束,使其必須繼承ISerializable。
        class One : ISerializable
        {
            
    public string Name { getset; }
            
    #region ISerializable 成員
            
    public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue(
    "Name", Name);
            }
            
    #endregion
            
    protected One(SerializationInfo info, StreamingContext context)
            {
                Name 
    = info.GetString("Name");
            }
        }
        [Serializable]
        
    class Program<T> where T : ISerializable
        {
            
    public T Name { getset; }
        }
        
    class Program
        {
            
    static void Main(string[] args)
            {
                Program
    <One> pro = new Program<One>();
                BinaryFormatter formatter 
    = new BinaryFormatter();
                Stream stream 
    = new MemoryStream();
                formatter.Serialize(stream, pro);
                Console.ReadLine();
            }
        }
  3. 為泛型類新增靜態初始化器,進行泛型型別引數檢查,如果是不可序列化,則丟擲SerializationException異常。
    <!--

    Code highlighting produced by Actipro CodeHighlighter (freeware)
    http://www.CodeHighlighter.com/

    --&gt    class One
        {
            
    public string Name { getset; }
        }
        [Serializable]
        
    class Program<T>
        {
            
    static Program()
            {
                ContrainType(
    typeof(T));
            }
            
    static void ContrainType(Type type)
            {
                
    if (!type.IsSerializable)
                {
                    
    throw new SerializationException(type.Name + "不可序列化");
                }
                
    if (type.IsGenericType)
                {
                    Type[] typeArr 
    = type.GetGenericArguments();
                    Array.ForEach(typeArr, ContrainType);
                }
            }
            
    public T Name { getset; }
        }
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    try
                {
                    Program
    <One> pro = new Program<One>();
                }
                
    catch (Exception ex)
                {
                    
    // “MyConsoleApplication.Program`1”的型別初始值設定項引發異常。
                    Console.WriteLine(ex.Message);
                    
    // One不可序列化
                    Console.WriteLine(ex.InnerException.Message);
                }
                Console.ReadLine();
            }
        }

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-617464/,如需轉載,請註明出處,否則將追究法律責任。

相關文章