繁体   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