tôi nhận được một ProtoException
("Có thể đệ quy phát hiện (offset: 4 mức (s)): o EOW") khi tuần tự một cấu trúc cây như vậy:Serialize tiền tố cây
var tree = new PrefixTree();
tree.Add("racket".ToCharArray());
tree.Add("rambo".ToCharArray());
using (var stream = File.Open("test.prefix", FileMode.Create))
{
Serializer.Serialize(stream, tree);
}
Việc thực hiện cây:
[ProtoContract]
public class PrefixTree
{
public PrefixTree()
{
_nodes = new Dictionary<char, PrefixTree>();
}
public PrefixTree(char[] chars, PrefixTree parent)
{
if (chars == null) throw new ArgumentNullException("chars");
if (parent == null) throw new ArgumentNullException("parent");
if (chars.Length == 0) throw new ArgumentException();
_parent = parent;
_nodes = new Dictionary<char, PrefixTree>();
_value = chars[0];
var overflow = chars.SubSet(1);
if (!overflow.Any()) _endOfWord = true;
else Add(overflow.ToArray());
}
[ProtoMember(1)]
private readonly char _value;
[ProtoMember(2)]
private readonly bool _endOfWord;
[ProtoMember(3)]
private readonly IDictionary<char, PrefixTree> _nodes;
[ProtoMember(4, AsReference = true)]
private readonly PrefixTree _parent;
public void Add(char[] word)
{
if (word == null) throw new ArgumentNullException("word");
if (word.Length == 0) return;
var character = word[0];
PrefixTree node;
if (_nodes.TryGetValue(character, out node))
{
node.Add(word.SubSet(1));
}
else
{
node = new PrefixTree(word, this);
_nodes.Add(character, node);
}
}
public override string ToString()
{
return _endOfWord ? _value + " EOW" : _value.ToString();
}
}
public static class ListHelper
{
public static char[] SubSet(this char[] source, int start)
{
return source.SubSet(start, source.Length - start);
}
public static char[] SubSet(this char[] source, int start, int length)
{
if (start < 0) throw new ArgumentOutOfRangeException();
if (start > source.Length) throw new ArgumentOutOfRangeException();
if (length < 0) throw new ArgumentOutOfRangeException();
var result = new char[length];
Array.Copy(source, start, result, 0, length);
return result;
}
}
Tôi có trang trí với các thuộc tính sai hoặc tôi đã thiết kế đơn giản cây không có thể tuần tự không?
Edit: cố gắng này không có kết quả:
var typeModel = RuntimeTypeModel.Default;
var type = typeModel.Add(typeof(PrefixTree), false);
type.AsReferenceDefault = true;
type.Add("_value", "_endOfWord", "_nodes", "_parent");
var tree = new PrefixTree();
tree.Add("racket".ToCharArray());
tree.Add("rambo".ToCharArray());
using (var stream = File.Open("test.prefix", FileMode.Create))
{
typeModel.Serialize(stream, tree);
}
Phương pháp mở rộng 'SubSet' của bạn là gì? cần phải hiểu rằng để có được một repro làm việc. Cũng thế; phương pháp 'Add' là gì? –
Tuy nhiên! Vấn đề chính ở đây là trình xử lý "từ điển" không sử dụng kiểu tham chiếu theo mặc định. Tôi có thể xem xét nhiều hơn nếu tôi có thể nhận được một repro làm việc. –
Chỉnh sửa lại, vẫn còn có "Lỗi Không có quá tải cho phương pháp 'SubSet' có 2 đối số" - trong phương thức ListHelper.SubSet –