2

我正在尝试使用包含不可变集合作为成员的 protobuf-net 序列化一个类。

集合类型 ,ImmutableList<T>实现ICollection<T>但返回属性trueIsReadOnly因此,任何修改它的尝试都会引发异常。

Protobuf-net 似乎依赖于在创建集合后能够调用Add(T)以填充它。这显然不适用于不可变集合,这是一种耻辱,因为 protobuf-net 可以很好地与我的所有其他数据类型一起工作,这些数据类型也是不可变的。

所以我的问题是,我必须有哪些选项才能序列化这些集合?


代码ImmutableList<T>如下:

public sealed class ImmutableList<T> : IList<T>, IList
{
    private readonly T[] m_Items;

    public ImmutableList(IEnumerable<T> source)
    {
        m_Items = source.ToArray();
    }

    public T[] ToArray()
    {
        T[] newArray = new T[m_Items.Length];
        m_Items.CopyTo(newArray, 0);
        return newArray;
    }

    private static void ThrowNotSupported()
    {
        throw new NotSupportedException("The attempted operation was not supported as the collection is read-only.");
    }

    #region IList<T> Members

    int IList.Add(object value)
    {
        ThrowNotSupported();
        return -1;
    }

    void IList.Clear()
    {
        ThrowNotSupported();
    }

    void IList<T>.Insert(int index, T item)
    {
        ThrowNotSupported();
    }

    void IList.Insert(int index, object value)
    {
        ThrowNotSupported();
    }

    void IList.Remove(object value)
    {
        ThrowNotSupported();
    }

    void IList.RemoveAt(int index)
    {
        ThrowNotSupported();
    }

    void IList<T>.RemoveAt(int index)
    {
        ThrowNotSupported();
    }

    T IList<T>.this[int index]
    {
        get
        {
            return m_Items[index];
        }
        set
        {
            ThrowNotSupported();
        }
    }

    object IList.this[int index]
    {
        get
        {
            return m_Items[index];
        }
        set
        {
            ThrowNotSupported();
        }
    }

    public T this[int index]
    {
        get
        {
            return m_Items[index];
        }
    }

    bool IList.Contains(object value)
    {
        return Array.IndexOf(m_Items, value) != -1;
    }

    int IList.IndexOf(object value)
    {
        return Array.IndexOf(m_Items, value);
    }

    public int IndexOf(T item)
    {
        return Array.IndexOf(m_Items, item);
    }

    bool IList.IsFixedSize
    {
        get
        {
            return true;
        }
    }

    #endregion

    #region ICollection<T> Members

    void ICollection<T>.Add(T item)
    {
        ThrowNotSupported();
    }

    void ICollection<T>.Clear()
    {
        ThrowNotSupported();
    }

    bool ICollection<T>.Remove(T item)
    {
        ThrowNotSupported();
        return false;
    }

    object ICollection.SyncRoot
    {
        get
        {
            return m_Items;
        }
    }

    bool ICollection.IsSynchronized
    {
        get
        {
            return true;
        }
    }

    public bool Contains(T item)
    {
        return IndexOf(item) != -1;
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        m_Items.CopyTo(array, arrayIndex);
    }

    void ICollection.CopyTo(Array array, int index)
    {
        m_Items.CopyTo(array, index);
    }

    public int Count
    {
        get
        {
            return m_Items.Length;
        }
    }

    public bool IsReadOnly
    {
        get
        {
            return true;
        }
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return ((IEnumerable<T>)m_Items).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return m_Items.GetEnumerator();
    }

    #endregion
}
4

1 回答 1

2

目前没有对此的支持;但这似乎是一个合理的情况。这取决于“开箱即用”的意思(评论);如果您的意思是“今天,没有更改代码”,则需要对 DTO 使用代理项,或者将不可变列表公开为可变列表的 shim 属性;如果您的意思是“向前移动”,我怀疑我们可以查看采用 (perferable)IEnumerable[<T>]或 (不太可取,但可行)T[]的列表构造函数,并在缓冲数据后简单地构造列表。

于 2013-05-02T11:39:24.433 回答