2008-11-06 37 views
2

有沒有其他人遇到過這個問題?我有一個方法,在泛型類中調用帶有委託的泛型方法。我已經將該類標記爲可序列化,並且它沒有任何抱怨地進行序列化。但是,當我試圖反序列化這個類的一個對象時,它會掛住CPU並掛起機器。在通用類中調用泛型方法的委託在反序列化過程中固定CPU

代碼示例:

public delegate T CombinationFunctionDelegate<T,U,V>(U a, V b); 

    [Serializable] 
public class SDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
{ 
    public SDictionary() 
     : base() 
    { 
    } 

    protected SDictionary(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    {} 

    [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 
    public override void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     base.GetObjectData(info, context); 
    } 

    public List<ListItem> ToListItems() 
    { 
     return Convert(delegate(TKey key, TValue value) 
     { 
      return new ListItem(key.ToString(), value.ToString()); 
     }); 
    } 

    public List<U> Convert<U>(CombinationFunctionDelegate<U, TKey, TValue> converterFunction) 
    { 
     List<U> res = new List<U>(); 
     foreach (TKey key in Keys) 
      res.Add(converterFunction(key, this[key])); 

     return res; 
    } 
} 

我可以把一個實例該類到ViewState中(例如)就好了,但是當我再次嘗試提取ViewState的對象,在機器尖峯CPU和反序列化調用永遠不會返回(即無限循環)。

當我刪除ToListItems()方法時,一切都很好用。這真的很奇怪,還是我不明白序列化? =)

回答

0

首先,字典<>已經實現了ISerializable,所以你不需要指定explicity!

其次,你重寫GetObjectData(),但你似乎沒有調用Dictionary.GetObjectData(),所以字典可能不會被反序列化?因此,當你訪問這個鍵時,你最終會遇到「一個問題」。

是的,我想大聲這裏;)

也許你可以試試這個:

public override void GetObjectData(SerializationInfo info, StreamingContext context) 
{ 
    // deserialize the dictionary first 
    base.GetObjectData(info, context); 

    // the rest of your code 
    // ... 
} 

我沒有嘗試過或編譯的這一點,但它可能是值得考慮的?

祝你好運:)

+0

嘿感謝的想法。我編輯我的帖子,以顯示該類的更簡單的版本,提供相同的問題,包括您的建議。我仍然認爲它真的很奇怪=) – Badjer 2008-11-07 00:25:30

1

這是我目前有的代碼,它工作正常嗎?

[Serializable] 
    public class SDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
    { 
     public SDictionary() 
      : base() 
     { 
     } 

     protected SDictionary(SerializationInfo info, StreamingContext context) 
      : base(info, context) 
     { 
     } 

     public List<ListItem> ToListItems() 
     { 
      return this.Convert(delegate(TKey key, TValue value) 
      { 
       return new ListItem(key.ToString(), value.ToString()); 
      }); 
     } 

     public List<U> Convert<U>(CombinationFunctionDelegate<U, TKey, TValue> converterFunction) 
     { 
      List<U> res = new List<U>(); 
      foreach (TKey key in Keys) 
       res.Add(converterFunction(key, this[key])); 

      return res; 
     } 


    } 

    class Program 
    { 

     static void Main(string[] args) 
     { 
      SDictionary<string, string> b = new SDictionary<string, string>(); 
      b.Add("foo", "bar"); 

      System.IO.MemoryStream memStream = new System.IO.MemoryStream(); 
      System.Runtime.Serialization.Formatters.Binary.BinaryFormatter f = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
      f.Serialize(memStream, b); 
      memStream.Position = 0; 

      b = f.Deserialize(memStream) as SDictionary<string, string>; 
     } 

    } 

這有幫助嗎?

編輯:再次調整。

0

難道是匿名方法引用它駐留的實例嗎?我無法回答。

您的評論表明這是可能的。這是最簡單的方法:不要使用匿名方法。

public ListItem ToListItem(TKey key, TValue value) 
{ 
    return new ListItem(key.ToString(), value.ToString()); 
} 

我可以回答,是這個類的方法可以對字典< T,U>的公共合同發放,因此沒有必要爲這個類時,你可以寫針對詞典< T,U>擴展方法(假設C#3)

像這樣(徒手代碼,所以可能不是100%正確)

public static List<ListItem> ToListItems(this Dictionary<T, U> source) 
{ 
    return source 
    .Select(x => new ListItem(x.key.ToString(), x.value.ToString())) 
    .ToList(); 
} 

public static List<V> Convert<V> 
(
    this Dictionary<T, U> source, 
    Func<T, U, V> converterFunction 
) 
{ 
    return source 
    .Select(x => converterFunction(x.Key, x.Value)) 
    .ToList(); 
} 
+0

Ahhhh - 好的想法 - 代理的閉包會包含對象本身,所以在反序列化對象時可能會陷入無限循環。 我會使用C#3,但不幸的是目前不是一個選項=( 感謝您的幫助! – Badjer 2008-11-07 04:30:06

相關問題