[英]Compare and check if multiple variables, both reference types and value types, in object has changed in C#
在一个系统中,我们依赖第三方服务,并且每分钟我们都会从第三方服务下载数据并更新我们的数据。 它与电子签名有关,因此有很多字段需要更新。 现在,我们正在获取所有信息,然后即使没有任何更改也要在我们这边进行更新。
我的想法是使用下面显示的任何方法进行深层复制,然后比较这些值。 但是,由于变量太多,我想知道是否可以通过某种方式比较所有值,看看它们是否相等,而不必编写代码来检查每个变量? 如下所示的协议具有值和参考类型。
public class Agreement
{
//Properties here, both value and reference types
public bool HasChanged(Agreement oldagreement)
{
//Code here
}
}
方法示例:
var oldagreement = agreement.Clone();
var document = client.GetThirdPartyAgreement(agreement.AgreementDocumentId);
UpdateDocument(agreement, document);
if(agreement.HasChanged(oldagreement)
{
agreementRepository.Update(agreement);
}
深度复制扩展方法:
/// <summary>
/// Perform a deep Copy of the object, using Json as a serialisation method. NOTE: Private members are not cloned using this method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneJson<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
// initialize inner objects individually
// for example in default constructor some list property initialized with some values,
// but in 'source' these items are cleaned -
// without ObjectCreationHandling.Replace default constructor values will be added to result
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to 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 be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that 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);
}
}
我使用@ LasseV.Karlsen的技巧使它起作用。 我遇到的一个问题是DateTimes。 当我在C#中比较DateTime对象时,它们相等,但是当调用方法Newtonsoft.Json.JsonConvert.SerializeObject()
,它们生成了一个不同的时间字符串。 这些是生成的字符串2016-10-21T10:42:09+02:00
和2016-10-21T10:42:09
。
我通过扩展Newtonsoft.Json.Converters.IsoDateTimeConverter
来解决此问题,如下面的代码所示。 之后,所有DateTime对象都具有相同的格式。
public class CustomDateTimeConverter : IsoDateTimeConverter
{
public CustomDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-ddTHH:mm:sszzz";
}
}
工作方法示例:
//CloneJson is the extension method from 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.