c#判斷兩個對象和對象中的屬性是否相同(以及記錄對象中的哪些字段,和詳細的改變情況)


當前項目需要記錄變更記錄,即用戶在進行編輯后,將變更操作記錄下來。但是數據沒有發生變化,則不記錄。

代碼1:(僅僅返回是否變化的標識)

    /// <summary>
    /// 反射對比實體屬性變更
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CompareEntry<T>
    {
        /// <summary>
        /// 編輯之前的對象和編輯后的對象進行對比
        /// </summary>
        /// <returns></returns>
        public bool CompareDTO(T BeforeDTO, T AfterDTO)
        {
            bool IsEqual = true;

            if (BeforeDTO == null || AfterDTO == null)
            {
                IsEqual = false;
            }
            else if (BeforeDTO.Equals(DBNull.Value) || AfterDTO.Equals(DBNull.Value))
            {
                IsEqual = false;
            }else if (BeforeDTO.GetType() != AfterDTO.GetType())
            {
                IsEqual = false;
                return IsEqual;
            }
            else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
            {
                //int 01與1      
                if (BeforeDTO is int)
                {
                    if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
                else if (BeforeDTO is short)
                {
                    if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
                else if (BeforeDTO is long)
                {
                    if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
                else if (BeforeDTO is float)
                {
                    if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
                else if (BeforeDTO is double)
                {
                    if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
                else if (BeforeDTO is decimal)
                {
                    if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
                    {
                        IsEqual = false;
                    }
                }
            }
            else 
            {
                var beforeMembers = BeforeDTO.GetType().GetProperties();
                var afterMembers = AfterDTO.GetType().GetProperties();
                for (int i = 0; i < beforeMembers.Length; i++)
                {
                    var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
                    var afterVal = afterMembers[i].GetValue(AfterDTO, null);
                    var beforeValue = beforeVal == null ? null : beforeVal.ToString();
                    var afterValue = afterVal == null ? null : afterVal.ToString();
                    if (beforeValue != afterValue)
                    {
                        IsEqual = false;
                        break;
                    }
                }
            }

            return IsEqual;       
        }
    }

 

調整后的代碼:(返回標識以及詳細變更記錄)

  /// <summary>
    /// 
    /// </summary>
    public class CompareResult
    {
        /// <summary>
        /// 
        /// </summary>
        public bool IsChange { get; set; }
        /// <summary>
        /// 變跟內容
        /// </summary>
        public string ChangeContent { get; set; }
    }

    /// <summary>
    /// 對比實體屬性變更(利用反射)
    /// </summary>
    public class CompareEntry
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CompareResult CompareDTO(object BeforeDTO, object AfterDTO)
        {
            CompareResult result = new CompareResult();
            bool b = false;

            if (BeforeDTO == null && AfterDTO != null)
            {
                b = true;
            }
            else if (BeforeDTO != null && AfterDTO == null)
            {
                b = true;
            }
            else if (BeforeDTO.Equals(DBNull.Value) && !AfterDTO.Equals(DBNull.Value))
            {
                b = true;
            }
            else if (!BeforeDTO.Equals(DBNull.Value) && AfterDTO.Equals(DBNull.Value))
            {
                b = true;
            }
            else if (BeforeDTO.GetType() != AfterDTO.GetType())
            {
                result.IsChange = true;
                return result;
            }
            else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
            {
                if (BeforeDTO is int)
                {
                    if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
                    {
                        b = true;
                    }
                }
                else if (BeforeDTO is short)
                {
                    if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
                    {
                        b = true;
                    }
                }
                else if (BeforeDTO is long)
                {
                    if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
                    {
                        b = true;
                    }
                }
                else if (BeforeDTO is float)
                {
                    if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
                    {
                        b = true;
                    }
                }
                else if (BeforeDTO is double)
                {
                    if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
                    {
                        b = true;
                    }
                }
                else if (BeforeDTO is decimal)
                {
                    if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
                    {
                        b = true;
                    }
                }
            }
            else 
            {
                StringBuilder content = new StringBuilder();
                var beforeMembers = BeforeDTO.GetType().GetProperties();
                var afterMembers = AfterDTO.GetType().GetProperties();
                for (int i = 0; i < beforeMembers.Length; i++)
                {
                    var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
                    var afterVal = afterMembers[i].GetValue(AfterDTO, null);
                    var beforeValue = beforeVal == null ? null : beforeVal.ToString();
                    var afterValue = afterVal == null ? null : afterVal.ToString();
                    if (beforeValue != afterValue)
                    {
                        b = true;
                        content.Append(beforeMembers[i].Name+"("+ beforeValue+"->"+afterValue+")");
                    }
                }
                result.IsChange = b;
                result.ChangeContent = content.ToString();
            }

            return result;       
        }
    }

注意,引用類型進行對比的時候,需要在編輯之前對對象進行拷貝,讓拷貝的對象與編輯后的對象進行對比。(因為引用類型不同於值類型,值類型每次操作都會產生一個新的對象,而引用類型在new一個新對象賦值時,其實是在堆上創建了一個內存地址,指向的仍然是原對象,對它操作原對象也會發生變化。所以只有通過拷貝復制一個新對象)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM