zhejiushizhuce / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
0 stars 0 forks source link

Enable (de)serialization of object properties containing a boxed primitive value. #175

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The relevant discussion is in 
http://stackoverflow.com/questions/6129612/help-needed-with-the-most-trivial-pro
tobuf-net-example-3
==============
The constructor ProtoBuf.Meta.MetaType.MetaType contains a check making sure 
that the given type is not primitive. Commenting out this check, makes it 
possible to (de)serialize an object property containing a boxed primitive value 
using the respective type surrogate. The aforementioned SO post contains a 
working example, utilizing int and IntSurrogate.

It seems necessary to allow primitive value types to be used in such scenarios 
without a need for the respective surrogate types.

Original issue reported on code.google.com by mark.kha...@gmail.com on 28 May 2011 at 7:16

GoogleCodeExporter commented 9 years ago
Do you plan to implement this issue in the near future?
Thanks.

Original comment by mark.kha...@gmail.com on 3 Jun 2011 at 7:57

GoogleCodeExporter commented 9 years ago
It is certainly high up there. I started hacking something in, but there were a 
number of edge cases with conflicting serialization that just needs to be 
treble checked to make sure it doesn't have unforeseen consequences (since the 
code checks for root types, and object would very-much be a root type).

I also need to ensure that this mechanism doesn't interfere with the existing 
"aux" serialization of basic types, as that would be a killer. Since that works 
by querying the key of, say, Int32 - I need to partition the data to avoid pain.

It is probably a go-er, but when you have to consider the full breath of 
possible setups it isn't *quite* as simple as removing an exception.

Original comment by marc.gravell on 3 Jun 2011 at 8:48

GoogleCodeExporter commented 9 years ago
I was not aware of the complexity. Thanks for working on it.

Original comment by mark.kha...@gmail.com on 4 Jun 2011 at 11:29

GoogleCodeExporter commented 9 years ago
Just to make sure - this is not supported yet, right?

Original comment by mark.kha...@gmail.com on 20 Jul 2011 at 10:58

GoogleCodeExporter commented 9 years ago
Not at current.

Original comment by marc.gravell on 21 Jul 2011 at 5:46

GoogleCodeExporter commented 9 years ago
Can you advise on how to process the following DTO:
  [DataContract]
  public class ParameterAttributeMetadata
  {
    [DataMember(Order = 1)]
    public string Id { get; set; }
    [DataMember(Order = 2)]
    public string Description { get; set; }
    [DataMember(Order = 3)]
    public string FriendlyName { get; set; }
    [XmlIgnore, JsonIgnore]
    public Type DataType { get; set; }
    [DataMember(Order = 5)]
    public object DefaultValue { get; set; }

    [DataMember(Order = 4)]
    [XmlElement("DataType"), JsonProperty("DataType")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public string DataTypeAsString
    {
      get { return ValueConverter.Default.Type2String(DataType); }
      set { DataType = ValueConverter.Default.String2Type(value); }
    }
  }

Where DataType can be any of the primitive types plus string.
Thank you very much.

Original comment by mark.kha...@gmail.com on 21 Jul 2011 at 7:08

GoogleCodeExporter commented 9 years ago
I am currently working around this issue by following these steps:
1. Comment the code in MetaType constructor which throws if a core type is 
given. This allows me to define the model at all.
2. Define all the core types that may be given as object with surrogates. This 
allows me to actually deserialize the stream.

Here is an example:

namespace HelloProtoBuf
{
  public static class TestCoreSurrogate<T>
  {
    [DataContract]
    public class A
    {
      [DataMember(Order = 1)]
      public object X { get; set; }
    }

    public static void Test(T value)
    {
      var m = TypeModel.Create();
      m.AutoCompile = false;
      m.Add(typeof(object), false).AddSubType(1, typeof(T));
      Surrogate<T>.Register(m);

      var o = new A { X = value };
      var o2 = (A)m.DeepClone(o);
      Debug.Assert(Equals(o.X, o2.X));
    }
  }

  class Program
  {
    static void Main()
    {
      TestCoreSurrogate<bool>.Test(true);
      TestCoreSurrogate<byte>.Test(5);
      TestCoreSurrogate<short>.Test(5);
      TestCoreSurrogate<int>.Test(5);
      TestCoreSurrogate<long>.Test(5);
      TestCoreSurrogate<double>.Test(5);
      TestCoreSurrogate<float>.Test(5);
      TestCoreSurrogate<string>.Test("5");
    }
  }

  internal class Surrogate<T>
  {
    public static void Register(RuntimeTypeModel m)
    {
      m.Add(typeof(Surrogate<T>), false).Add("Value");
      m.Add(typeof(T), false).SetSurrogate(typeof(Surrogate<T>));
    }
    public static implicit operator T(Surrogate<T> surrogate)
    {
      return surrogate.Value;
    }
    public static implicit operator Surrogate<T>(T v)
    {
      return new Surrogate<T> { Value = v };
    }

    internal T Value { get; set; }
  }
}

It is my subjective feeling, that using surrogates for the core types is not a 
wise idea performance wise, so I am looking forward for the resolution.

Thanks.

Original comment by mark.kha...@gmail.com on 24 Jul 2011 at 1:18

GoogleCodeExporter commented 9 years ago
I understand that fixing it takes some time. Is it possible for the time being 
to remove the check for the existence of the core serializer from the MetaType 
constructor? This way we can use boxed primitives through surrogates. 
Otherwise, there is no way. 

What do you say?

Original comment by mark.kha...@gmail.com on 26 Jul 2011 at 1:30

GoogleCodeExporter commented 9 years ago
If I remove that check, I cannot make any guarantees about the long-term 
ability to deserialize any data that you store using that option. The check is 
there to protect the user, not to cripple them.

Original comment by marc.gravell on 27 Jul 2011 at 10:09

GoogleCodeExporter commented 9 years ago
As long as this is not WontFix I can live with that. Any advice on the dto from 
http://code.google.com/p/protobuf-net/issues/detail?id=175#c6?

Thanks.

Envoyé de mon iPhone

Le 27 ביול 2011 à 13:14, protobuf-net@googlecode.com a écrit :

Original comment by mark.kha...@gmail.com on 27 Jul 2011 at 2:37