用 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;
}