Compare and check if multiple variables, both reference types and value types, in object has changed in C# -
in system dependent on third party service , once every minute download data them , update our data. related e-signing lot of fields update. right getting information , update on our side if nothing has changed.
my thought deep copy using of methods shown below , compare values. since there many variables wonder if there someway can compare values , see if equal , not have write code check each variable? agreement shown below have both value , reference types.
public class agreement { //properties here, both value , reference types public bool haschanged(agreement oldagreement) { //code here } }
method example:
var oldagreement = agreement.clone(); var document = client.getthirdpartyagreement(agreement.agreementdocumentid); updatedocument(agreement, document); if(agreement.haschanged(oldagreement) { agreementrepository.update(agreement); }
deep copy extension methods:
/// <summary> /// perform deep copy of object, using json serialisation method. note: private members not cloned using method. /// </summary> /// <typeparam name="t">the type of object being copied.</typeparam> /// <param name="source">the object instance copy.</param> /// <returns>the copied object.</returns> public static t clonejson<t>(this t source) { // don't serialize null object, return default object if (object.referenceequals(source, null)) { return default(t); } // initialize inner objects individually // example in default constructor list property initialized values, // in 'source' these items cleaned - // without objectcreationhandling.replace default constructor values added result var deserializesettings = new jsonserializersettings { objectcreationhandling = objectcreationhandling.replace }; return jsonconvert.deserializeobject<t>(jsonconvert.serializeobject(source), deserializesettings); } /// <summary> /// perform deep copy of object. /// </summary> /// <typeparam name="t">the type of object being copied.</typeparam> /// <param name="source">the object instance copy.</param> /// <returns>the copied object.</returns> public static t clone<t>(this t source) { if (!typeof(t).isserializable) { throw new argumentexception("the type must serializable.", "source"); } // don't serialize null object, return default object if (object.referenceequals(source, null)) { return default(t); } iformatter formatter = new binaryformatter(); stream stream = new memorystream(); using (stream) { formatter.serialize(stream, source); stream.seek(0, seekorigin.begin); return (t)formatter.deserialize(stream); } }
i got work using tip @lassev.karlsen. 1 problem had datetimes however. when compared datetime object in c# equal when metod newtonsoft.json.jsonconvert.serializeobject()
called generated different time string. these strings generated 2016-10-21t10:42:09+02:00
, 2016-10-21t10:42:09
.
i solved extending newtonsoft.json.converters.isodatetimeconverter
code below. afterwards datetime objects had same format.
public class customdatetimeconverter : isodatetimeconverter { public customdatetimeconverter() { base.datetimeformat = "yyyy-mm-ddthh:mm:sszzz"; } }
working method example:
//clonejson extension method above - deep copy var oldagreement = agreement.clonejson(); var document = client.getthirdpartyagreement(agreement.agreementdocumentid); updatedocument(agreement, document); var agreementstring = newtonsoft.json.jsonconvert.serializeobject(agreement, new customdatetimeconverter()); var oldagreementstring = newtonsoft.json.jsonconvert.serializeobject(oldagreement, new customdatetimeconverter()); if (agreementstring != oldagreementstring) { agreementrepository.update(agreement); }
Comments
Post a Comment