我正在尝试使用protobuf-net序列化一个类,其中包含一个不可变集合作为成员。
集合类型ImmutableList<T>
实现ICollection<T>
,但为true
属性返回IsReadOnly
。因此,任何修改它的尝试都会引发异常。
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
}
答案 0 :(得分:2)
目前没有人支持;但这似乎是一个合理的方案。这取决于你的意思(评论)“开箱即用”;如果你的意思是“今天,没有代码改变”,它将需要使用一个代理人来反对DTO,或一个将不可变列表暴露为可变列表的垫片属性;如果你的意思是“向前移动”,我怀疑我们可以查看采用(优先)IEnumerable[<T>]
或(不太优选,但可行)T[]
的列表构造函数,并在缓冲数据后简单地构造列表