在反序列化期间,委托在泛型类中调用泛型方法

时间:2008-11-06 23:52:57

标签: c# generics serialization

之前是否有其他人遇到此问题?我有一个方法,在泛型类中使用委托调用泛型方法。我已将该类标记为Serializable,并且它没有投诉地序列化。但是,当我尝试反序列化该类的对象时,它会挂起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()方法时,一切都运行得非常好。这真的很奇怪,还是我不理解序列化? =)

5 个答案:

答案 0 :(得分: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>;
        }

    }

这有帮助吗?

编辑:再次调整。

答案 1 :(得分:0)

首先,词典&lt;&gt;已经实现了ISerializable,所以你不需要指定明确的!

其次,你重写了GetObjectData(),但你似乎没有调用Dictionary.GetObjectData(),所以字典可能没有被反序列化?因此,当你访问this.Keys时,你最终会遇到“问题”。

是的,我在这里大声思考;)

也许你可以试试这个:

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

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

我没有尝试或编译过这个,但可能需要考虑一下?

祝你好运:)

答案 2 :(得分:0)

匿名方法是否可以引用它所驻留的实例?我无法回答这个问题。

您的评论表明这是可能的。这是最简单的方法:不要使用匿名方法。

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

我可以回答的是,这个类的方法可以根据Dictionary&lt;的公共合同发布。 T,U&gt;,所以当您可以针对Dictionary&lt;来编写扩展方法时,不需要这个类。 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();
}

答案 3 :(得分:0)

答案 4 :(得分:0)

以下是有关该错误的知识库文章,如果有人需要它:http://support.microsoft.com/?id=957543