2008-11-06 2 views
2

이전에이 문제를 겪은 사람이 있습니까? 제네릭 클래스 내에서 대리자를 사용하여 제네릭 메서드를 호출하는 메서드가 있습니다. 클래스를 Serializable로 표시하고 불만없이 직렬화합니다. 그러나이 클래스의 객체를 deserialize하려고하면 CPU가 멈춰서 컴퓨터가 중단됩니다.일반 클래스 내에서 일반 메서드를 호출하는 대리자는 역 직렬화 중에 CPU를 페그합니다.

코드 예제 : 나는 다시 기계 스파이크에 CPU를의 ViewState에서 개체를 추출하려고 할 때 (예를 들어)의 ViewState에이 클래스의 잘 인스턴스를 넣을 수 있지만,

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; 
    } 
} 

및 deserialization 호출은 절대 반환되지 않습니다 (즉, 무한 루프).

ToListItems() 메서드를 제거하면 모든 것이 훌륭하게 작동합니다. 이게 정말 이상한가요? 아니면 직렬화를 이해하지 못합니까? =)

답변

0

우선, 사전 <>은 이미 ISerializable을 구현하고 있으므로 해당 명시를 지정할 필요가 없습니다!

둘째, 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

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)는

이런

뭔가

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