38813

Is it possible to serialize/deserialize immutable types with protobuf-net on Windows Phone 7/8?

Question:

Is it possible to serialize/deserialize types with protobuf-net on Windows Phone 7/8?<br /> I've tried the code below, it seems Constructor skipping isn't supported (i.e. UseConstructor = false) so I created a parameterless constructor but the deserialization fails with "Attempt to access the method failed: Wp7Tests.ImmutablePoint.set_X(System.Double)"

public class ImmutablePoint { public double X { get; private set; } public double Y { get; private set; } public ImmutablePoint() {} public ImmutablePoint(double x, double y) { X = x; Y = y; } } public sub Test() { ImmutablePoint pt = new ImmutablePoint(1, 2); var model = TypeModel.Create(); var ptType = model.Add(typeof(ImmutablePoint), false); ptType.AddField(1, "X"); ptType.AddField(2, "Y"); IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication(); using (var stream1 = new IsolatedStorageFileStream("test.bin", FileMode.Create, store)) { try { model.Serialize(stream1, pt); } catch (Exception e) { Debugger.Break(); } } const double EPSILON = 0.001; using (var stream1 = new IsolatedStorageFileStream("test.bin", FileMode.Open, store)) { try { ImmutablePoint ptDeSer = (ImmutablePoint) model.Deserialize(stream1,null, typeof(ImmutablePoint)); Debug.Assert(Math.Abs(pt.X - ptDeSer.X) < EPSILON); Debug.Assert(Math.Abs(pt.Y - ptDeSer.Y) < EPSILON); } catch (Exception e) { Debugger.Break(); } } }

Answer1:

You can use a <em>surrogate</em>; here I'm decorating it with attributes, but it can be configured manually too:

[ProtoContract] public class MutablePoint { [ProtoMember(1)] public double X { get; set; } [ProtoMember(2)] public double Y { get; set; } public static implicit operator MutablePoint(ImmutablePoint value) { return value == null ? null : new MutablePoint {X=value.X, Y=value.Y}; } public static implicit operator ImmutablePoint(MutablePoint value) { return value == null ? null : new ImmutablePoint(value.X, value.Y); } }

and then tell the model to use this whenever it sees ImmutablePoint:

var model = TypeModel.Create(); model.Add(typeof(MutablePoint), true); model.Add(typeof(ImmutablePoint), false).SetSurrogate(typeof(MutablePoint));

The serializer will use the operators to switch between them as necessary. The serializer will use either implicit or explicit custom conversion operators.

EDIT: Deserialize like this

ImmutablePoint ptDeSer = (ImmutablePoint)model.Deserialize(stream1, null, typeof(ImmutablePoint));

Answer2:

This isn't possible on Windows Phone. The deserializer cannot access the setters and using reflection to access private members results in a MemberAccessException on Windows Phone. The only way I can think of getting something like this to work would be by creating a wrapper for serialization which can then call the constructor of your ImmutablePoint. It's all a bit messy though as the wrapper class will need public read-write properties for X and Y.

You could also look at using the InternalsVisibleTo attribute to allow the serializer to access the properties (assuming you change the setters from private to internal). Still messy though...

Recommend

  • QtGui.QIdentityProxyModel missing in PySide?
  • Cannot serialize member because it is an interface
  • How to write string.Contains(someText) in expression Tree
  • DependencyObject.AssociatedObject is always null
  • when does setTimeout start executing in a inline
  • How do I register classes by both interface and namespace with Windsor?
  • Linq Objects Group By & Sum
  • Can I display google adwords (AdView) in javafx on android
  • Align navbar back button on right side
  • How to add date and time under each post in guestbook in google app engine
  • How to set/get protobuf's extension field in Go?
  • DirectX11 ClearRenderTargetViewback with transparent buffer?
  • Validaiting emails with Net.Mail MailAddress
  • sending/ receiving email in Java
  • Web-crawler for facebook in python
  • Akka Routing: Reply's send to router ends up as dead letters
  • How to format a variable of double type
  • Cannot Parse HTML Data Using Android / JSOUP
  • Comma separated Values
  • Buffer size for converting unsigned long to string
  • Error creating VM instance in Google Compute Engine
  • using HTMLImports.whenReady not working in chrome
  • Hits per day in Google Big Query
  • Angular 2 constructor injection vs direct access
  • how does django model after text[] in postgresql [duplicate]
  • Getting Messege Twice Using IMvxMessenger
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • Authorize attributes not working in MVC 4
  • unknown Exception android
  • EntityFramework adding new object to nested object collection
  • MATLAB: Piecewise function in curve fitting toolbox using fittype
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • Observable and ngFor in Angular 2
  • How can i traverse a binary tree from right to left in java?
  • How can I use `wmic` in a Windows PE script?
  • UserPrincipal.Current returns apppool on IIS
  • Unable to use reactive element in my shiny app
  • How can I use threading to 'tick' a timer to be accessed by other threads?