c# - Avoiding default constructors and public property setters -
i'm working on project signalr, , i've got objects i'm going passing along through it. these objects explicitly created in back-end code, , i'd able enforce immutability , invariants on them. i'm running issue signalr requires me (well, newtonsoft.json), have default, no-args constructor , public setters on properties in order serialize , deserialize them on wire.
here's contrived example:
public class message{ public string text {get;set;} public int awesomeness {get;set;} } what i'd like, more along these lines (it should have readonly private fields , getter-only properties immutable, poco no methods, enough)
public class message { public string text {get;private set;} public int awesomeness {get;private set;} public message( string msg, int awesome){ if (awesome < 1 || awesome > 5){ throw new argumentoutofrangeexception("awesome"); } text = msg; awesomeness = awesome; } } if that, though, object can't deserialized signalr .net client library. can chuck default constructor in there, , make setters public, have remember not use them in code, , make sure no 1 else on team uses them without understanding.
i've kicked around idea of doing this, mark default constructor should never explicitly used:
[obsolete("bad! don't this!") public message(){} but can't use obsolete attribute on setter of property.
if wanted to, separate out "real" object dto representation , convert between them, i'm not psyched write bunch of boilerplate , introduce layer.
is there i'm overlooking, or need bite bullet , deal it?
if class not have public parameterless constructor, have single public constructor parameters, json.net call constructor, matching constructor arguments json properties name using reflection , using default values missing properties. matching name case-insensitive, unless there multiple matches differ in case, in case match becomes case sensitive. if do:
public class message { public string text { get; private set; } public int awesomeness { get; private set; } public message(string text, int awesomeness) { if (awesomeness < 1 || awesomeness > 5) { throw new argumentoutofrangeexception("awesome"); } this.text = text; this.awesomeness = awesomeness; } } you able serialize , deserialize class json.net.
prototype fiddle.
if class has multiple public constructors, parameters, can mark 1 use [jsonconstructor], e.g.:
public class message { public string text { get; private set; } public int awesomeness { get; private set; } public message(string text) : this(text, 1) { } [jsonconstructor] public message(string text, int awesomeness) { if (awesomeness < 1 || awesomeness > 5) { throw new argumentoutofrangeexception("awesome"); } this.text = text; this.awesomeness = awesomeness; } } see jsonserializersettings.constructorhandling tells json.net whether prefer non-public parameterless constructor on single public constructor parameters.
Comments
Post a Comment