[英]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.