I’m using protobuf-net v2 and have a class that inherits “List” that I wan’t to serialize/clone.
when I’m calling “DeepClone” (or deserialize) I’m getting the cloned object empty.
I can serialize the object into file and it seems to be serialized as expected but the RuntimeTypeModel can’t deserialized it back from the byte[].
the single solution I’ve found to overcome this issue is to use surrogate.
as said, if you’re skipping the “SetSurrogate” the clone is failed.
is there any other option to solve it?
attached:
class Program
{
static void Main(string[] args)
{
RuntimeTypeModel model = RuntimeTypeModel.Create();
model[typeof(Custom<string>)].SetSurrogate(typeof(Surrogate<string>));
var original = new Custom<string> { "C#" };
var clone = (Custom<string>)model.DeepClone(original);
Debug.Assert(clone.Count == original.Count);
}
}
[ProtoContract(IgnoreListHandling = true)]
public class Custom<T> : List<T> { }
[ProtoContract]
class Surrogate<T>
{
public static implicit operator Custom<T>(Surrogate<T> surrogate)
{
Custom<T> original = new Custom<T>();
original.AddRange(surrogate.Pieces);
return original;
}
public static implicit operator Surrogate<T>(Custom<T> original)
{
return original == null ? null : new Surrogate<T> { Pieces = original };
}
[ProtoMember(1)]
internal List<T> Pieces { get; set; }
}
Another thing I’ve found is when you’re replacing the ProtoContract attribute from the class “Custom” with “System.Serializable” attribute, it deserializing the byte[] as expected even without surrogate.
The problem here is simply the fact that you explicitly turned off the list-handling, via:
Which, as the name suggests and the documentation verifies:
So: there was nothing useful left to do, as
Custom<T>doesn’t have any other data-members to serialize.So: if you aren’t using the surrogate, don’t disable list-handling. The main purpose of this option is for edge-cases where something that is intended to be an “object” also has features that make it look temptingly like a list (all protobuf-net needs is
IEnumerable[<T>]and a handyAdd(T)method).