簡體   English   中英

比較並檢查對象中的多個變量(引用類型和值類型)在C#中是否已更改

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM