C# 方便的复制/比较物件内数据的方法(Object Copy / Compare)

用 Collection / Object 时经常想用一个物件(Object)去生成另一个物件并保留原有数据(如 DataTable.Copy()),最没头没脑的做法是:

view plaincopy to clipboardprint?
public MyObject Copy()  
{  
    MyObject oNewObject = new MyObject();  
    oNewObject.Value1 = this.Value1;   
    oNewObject.Value2 = this.Value2;  
    oNewObject.Value3 = this.Value3;  
    return oNewObject;  
}  
public bool Compare(MyObject oNewObject)  
{  
    return (oNewObject.Value1 == this.Value1   
        && oNewObject.Value2 == this.Value2   
        && oNewObject.Value3 == this.Value3);  

public MyObject Copy()
{
 MyObject oNewObject = new MyObject();
 oNewObject.Value1 = this.Value1;
 oNewObject.Value2 = this.Value2;
 oNewObject.Value3 = this.Value3;
 return oNewObject;
}
public bool Compare(MyObject oNewObject)
{
 return (oNewObject.Value1 == this.Value1
  && oNewObject.Value2 == this.Value2
  && oNewObject.Value3 == this.Value3);
}

如果每个物件(Object )只有十多个属性(Properties)的话这样只是小菜一碟,但当你有数十个物件...每个物件有数十个属性的话,那就有够脑残了...

以下是用Reflection的PropertyInfo去提取物件属性的例子:

view plaincopy to clipboardprint?
using System.Reflection;  
.  
.  
.  
for(int i = 0; i < oOldObject.GetType().GetProperties().Length; i ++)  
{  
    //根据索引提取个别属性  
    PropertyInfo oOldObjectProperty = (PropertyInfo) oOldObject.GetType().GetProperties().GetValue(i);  
    //得到该属性的数据  
    Object oOldObjectValue = oOldObjectProperty.GetValue(oOldObject, null);  
    if (oOldObjectProperty.CanRead)  
    {  
        Console.WriteLine(oOldObjectProperty.Name + " = " + oOldObjectValue.ToString());  
    }  

using System.Reflection;
.
.
.
for(int i = 0; i < oOldObject.GetType().GetProperties().Length; i ++)
{
 //根据索引提取个别属性
 PropertyInfo oOldObjectProperty = (PropertyInfo) oOldObject.GetType().GetProperties().GetValue(i);
 //得到该属性的数据
 Object oOldObjectValue = oOldObjectProperty.GetValue(oOldObject, null);
 if (oOldObjectProperty.CanRead)
 {
  Console.WriteLine(oOldObjectProperty.Name + " = " + oOldObjectValue.ToString());
 }
}

如此便能列出物件中的所有属性,用同样的方法应该就能轻松复制/比较两个物件了:

view plaincopy to clipboardprint?
using System.Reflection;  
.  
.  
.  
public MyObject Copy()  
{  
    MyObject oNewObject = new MyObject();     
 
    for(int i = 0; i < this.GetType().GetProperties().Length; i ++)     
    {  
        PropertyInfo oOldObjectProperty = (PropertyInfo) this.GetType().GetProperties().GetValue(i);     
        Object oOldObjectValue = oOldObjectProperty.GetValue(this, null);     
 
        PropertyInfo oNewObjectProperty = (PropertyInfo) oNewObject.GetType().GetProperties().GetValue(i);     
 
        if (oOldObjectProperty.CanRead)     
        {  
            //设定oNewObject的当前属性的值为oOldObjectValue(数据类型必须(必定)一致)  
            oNewObjectProperty.SetValue(oNewObject, oOldObjectValue, null);  
        }  
    }  
 
    return oNewObject;  
}     
 
 
public bool Compare(MyObject oNewObject)     
{     
    bool bResult = true;     
 
    for(int i = 0; i < this.GetType().GetProperties().Length; i ++)     
    {     
        PropertyInfo oOldObjectProperty = (PropertyInfo) this.GetType().GetProperties().GetValue(i);     
        Object oOldObjectValue = oOldObjectProperty.GetValue(this, null);     
 
        PropertyInfo oNewObjectProperty = (PropertyInfo) oNewObject.GetType().GetProperties().GetValue(i);     
        Object oNewObjectValue = oNewObjectProperty.GetValue(oNewObject, null);     
 
        //防止属性是NULL  
        if (oOldObjectValue != null && oNewObjectValue != null)  
        {  
            switch(oOldObjectProperty.PropertyType.ToString())     
            {     
                case "System.Double":  
                    //Double 会有机会变成如2.49999999...的无限小数, 变成String才准确  
                    bResult = (((double)oOldObjectValue).ToString("0.000000") == ((double)oNewObjectValue).ToString("0.000000"));     
                    break;     
                case "System.DateTime":     
                    //量度到秒就够了  
                    bResult = (((DateTime)oOldObjectValue).ToString("yyyy/MM/dd HH:mm:ss") == ((DateTime)oNewObjectValue).ToString("yyyy/MM/dd HH:mm:ss"));     
                    break;     
                case "System.Boolean":  
                    bResult = (((bool)oOldObjectValue) == ((bool)oNewObjectValue));     
                    break;     
                default:     
                    bResult = (oOldObjectValue.ToString() == oNewObjectValue.ToString());     
                    break;     
            }  
        }  
        else 
        {  
            //验证个别属性是NULL  
            if (!(oOldObjectValue == null && oOldObjectValue == null))  
            {  
                bResult = false;  
            }  
        }  
 
        //如发现有不同就不用再比对了  
        if (!bResult)     
        {  
            break;     
        }     
    }     
 
    return bResult;     
}   

原文地址:https://www.cnblogs.com/lzjsky/p/2091886.html