2011-12-11 104 views
2

我最近遷移到protobuf網的新版本,我開始收到此錯誤消息後的Protobuf - 遷移到新版本

重複數據(列表,收藏等)具有內置的行爲,不能作爲子類

調用堆棧跟蹤

protobuf-net.dll!ProtoBuf.Meta.MetaType.AddSubType(int fieldNumber = 1, System.Type derivedType = {Name = "InfoColumn`1" FullName = "Om.Common.InfoSet.InfoColumn`1[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}) Line 83 C# 
protobuf-net.dll!ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour() Line 431 + 0x32 bytes C# 

任何這方面的幫助表示讚賞。我打算將我的代碼回滾到以前版本的protobuf-net

以下是類信息。

[DataContract] 
[ProtoInclude(1, typeof(InfoColumn<Double>))] 
[ProtoInclude(2, typeof(InfoColumn<String>))] 
[ProtoInclude(3, typeof(InfoColumn<DateTime>))] 
[ProtoInclude(4, typeof(InfoColumn<Boolean>))] 
public abstract class IInfoColumnBase 
{ 
    [DataMember(Order = 101)] 
    public abstract bool IsSingleValue { get; set; } 

    [DataMember(Order = 102)] 
    public abstract string Name { get; set; } 

    [DataMember(Order = 103)] 
    public abstract InfoColumnDataType DataType { get; set; } 
    public abstract long Insert(); 
    public abstract void Insert(long index); 
    public abstract void SetValue(long index, object val); 
    public abstract void CopyValues(long start, long end, IInfoColumnBase destCol, long index); 
    public abstract long GetIndex(object val); 
    public abstract void Remove(long index); 
    public abstract object GetValue(long index); 
    public abstract object GetInternalArrayValue(long index); 
    public abstract void Clear(); 
    public abstract long Count { get; } 
    public abstract long ArrayCount { get; } 
} 

public interface IInfoColumn<T> : IEnumerable<T> 
{ 
    T this[double index] { get; set; } 
    InfoTable Table { get; set; } 
    double Add(T item); 
} 


[DataContract(Name = "InfoColumn{0}")] 
[KnownType(typeof(InfoColumn<double>))] 
[KnownType(typeof(InfoColumn<String>))] 
[KnownType(typeof(InfoColumn<bool>))] 
[KnownType(typeof(InfoColumn<DateTime>))] 
public class InfoColumn<T> : IInfoColumnBase, IInfoColumn<T> 
{ 
    long counter = 0; 
    [DataMember(Order = 1)] 
    public IList<T> Values { get; set; } 

    //[DataMember(Order = 2)] 
    bool isSingleVal = false; 

    //[DataMember(Order=3)] 
    public override string Name { get; set; } 

    //[DataMember(Order=4)] 
    public override InfoColumnDataType DataType { get; set; } 

    public InfoTable Table { get; set; } 


    public override long Count 
    { 
     get 
     { 
      return this.Table.Count; 
     } 
    } 

    public override long ArrayCount 
    { 
     get { return this.Values.Count; } 
    } 

    public InfoColumn() 
    { 
    } 

    public InfoColumn(string name,InfoTable table) 
    { 
     this.Values = new List<T>(); 
     this.Name = name; 
     this.Table = table; 
    } 

    public override void Clear() 
    { 
     this.Values = new List<T>(); 
    } 

    public override void Remove(long index) 
    { 
     int newindex = (int)index; 
     this.Values.RemoveAt(newindex); 

    } 



    public override void CopyValues(long start, long end, IInfoColumnBase destCol, long startIndex) 
    { 
     InfoColumn<T> typeCol = destCol as InfoColumn<T>; 
     for (long ctr = start; ctr <= end; ctr++) 
     { 
      typeCol.SetValue(startIndex, this.Values[(int)ctr]); 
      startIndex++; 
     } 
    } 

    public override void Insert(long rows) 
    { 

     if (this.IsSingleValue == true) return; 

     for (int ctr = 0; ctr < rows; ctr++) 
     { 
      this.Values.Add(default(T)); 
     } 
    } 

    public T this[double a] 
    { 
     get 
     { 
      if (a >= this.Count) throw new IndexOutOfRangeException(); 
      long index = (long)a; 
      if (this.Table.IsFreezed == false) 
       index = this.Table.CheckData(a); 


      if (this.isSingleVal == true) 
       return this.Values[0]; 
      else 
       return this.Values[(int)index]; 
     } 
     set 
     { 
      if (a >= this.Count) throw new IndexOutOfRangeException(); 

      long index = (long)a; 

      if (this.Table.IsFreezed == false) 
       index = this.Table.CheckData(a); 

      if (this.isSingleVal == true) 
       this.Values[0] = value; 
      else 
       this.Values[(int)index] = value; 

     } 
    } 

    public override long GetIndex(object val) 
    { 
     T item = (T)val; 
     return this.Values.IndexOf(item); 
    } 

    public override void SetValue(long index, object val) 
    { 
     if (val is InfoSetLink) 
      this.Values[(int)index] = (T)val; 
     else 
      this.Values[(int)index] = (T)Convert.ChangeType(val, typeof(T)); 
    } 

    public override object GetValue(long index) 
    { 
     return this[index]; 
    } 

    public override object GetInternalArrayValue(long index) 
    { 
     return this.Values[(int)index]; 
    } 


    //[DataMember(Order=5)] 
    public override bool IsSingleValue 
    { 
     get { return isSingleVal; } 
     set 
     { 
      if (isSingleVal == true) 
      { 
       this.Values = new List<T>(1); 
      } 
     } 
    } 

    public override long Insert() 
    { 
     if (this.IsSingleValue == true) return -1; 
     this.Values.Add(default(T)); 
     return this.Values.Count - 1; 
    } 

    public double Add(T item) 
    { 
     this.Values.Add(item); 
     return this.Values.Count - 1; 
    } 

    #region IEnumerable<T> Members 

    public IEnumerator<T> GetEnumerator() 
    { 
     return new InfoColumnEnumerator<T>(this); 
    } 

    #endregion 

    #region IEnumerable Members 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return new InfoColumnEnumerator<T>(this); 
    } 

    #endregion 


} 
+0

我的心理調試器今天不工作;你能給我一個**提示**你的類型模型在這裏的樣子嗎?例如,「InfoColumn 」是什麼樣的?它有什麼基類型和派生類型?它實現了什麼接口?它有一個'Add()'方法(這可能很重要)? –

+0

我已更新原始問題的課堂結構。感謝您的答覆。 – GammaVega

+0

重新回答我的問題; r480已經上傳到nuget和谷歌代碼 –

回答

0

InfoColumn<T>具有公共Add(T)並實現IEnumerable<T>(經由IInfoColumn<T>)。

對v2中的類列表類型有更廣泛的支持,它可能是它試圖將上述解釋爲列表。確實,它看起來很像!我會試着去看看這種一般情況是否可以被檢測和避免,但這是一個邊緣情況(因爲它確實非常流行)。

有一個現有的IgnoreListBehaviour開關,但是這驗證了上面顯示的模型時,似乎對於這種特定情況下的:「你不能這樣做」禁用清單處理代碼之前,火災;我已經在源代碼中改變了這一點,這將包含在下一個版本中。基本上,你可以通過添加解決這個問題:

[ProtoContract(IgnoreListHandling = true)] 

到受影響的類型(InfoColumn<T>),與下一個構建。這將是很快,一旦我完成驗證等。

+0

感謝Marc快速轉身。我拉起最新版本,添加上面的屬性後,它確實修復了我的代碼。 – GammaVega