C# 比较c中的(特定)对象属性#
基于C语言中比较对象的答案# 知道这是一个复杂的主题,我想处理一些更具体的结构 如果属性是简单的值类型(如此对象),则此代码将匹配这些属性:C# 比较c中的(特定)对象属性#,c#,C#,基于C语言中比较对象的答案# 知道这是一个复杂的主题,我想处理一些更具体的结构 如果属性是简单的值类型(如此对象),则此代码将匹配这些属性: public class BasicStuff { public int anInt { get; set; } public bool aBool { get; set; } } 但一旦变得更复杂,这段代码就会失败 因此,我想做的是使其更适用于上述嵌套对象,例如: public class NestedStuff { publ
public class BasicStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
}
但一旦变得更复杂,这段代码就会失败
因此,我想做的是使其更适用于上述嵌套对象,例如:
public class NestedStuff
{
public BasicStuff theBasic { get; set; }
}
public class ArrayStuff
{
public BasicStuff[] theBasicArray { get; set; }
}
上述任意数组,例如:
public class NestedStuff
{
public BasicStuff theBasic { get; set; }
}
public class ArrayStuff
{
public BasicStuff[] theBasicArray { get; set; }
}
最后是上述各项的任意组合:
public class AllTheStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
public BasicStuff theBasic { get; set; }
public BasicStuff[] theBasicArray { get; set; }
}
所以我想到的是:
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
string t = AValue.GetType().ToString();
if (!AllPublicPropertiesEqual<object>(AValue, BValue))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual<object>(BValue, AValue))
return false;
}
else
{
object selfValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object toValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
public static bool AllPublicPropertiesEqual(T AObj,T BObj,params string[]ignore),其中T:class
{
if(AObj!=null&&BObj!=null)
{
类型=类型(T);
列表忽略列表=新列表(忽略);
foreach(type.GetProperties(BindingFlags.Public | BindingFlags.Instance)中的PropertyInfo pInfo)
{
如果(!ignoreList.Contains(pInfo.Name))
{
if(pInfo.PropertyType.IsArray)
{
object AValue=type.GetProperty(pInfo.Name).GetValue(AObj,null);
对象BValue=type.GetProperty(pInfo.Name).GetValue(BObj,null);
字符串t=AValue.GetType().ToString();
如果(!AllPublicPropertiesEqual(AValue,BValue))
返回false;
}
如果(!pInfo.PropertyType.IsValueType&&!pInfo.PropertyType.IsPrimitive&&!pInfo.PropertyType.IsEnum&&pInfo.PropertyType!=类型(字符串))
//else if(Convert.GetTypeCode(pInfo.PropertyType)==TypeCode.Object)
{
object AValue=type.GetProperty(pInfo.Name).GetValue(AObj,null);
对象BValue=type.GetProperty(pInfo.Name).GetValue(BObj,null);
如果(!AllPublicPropertiesEqual(BValue,AValue))
返回false;
}
其他的
{
object selfValue=type.GetProperty(pInfo.Name).GetValue(AObj,null);
objecttovalue=type.GetProperty(pInfo.Name).GetValue(BObj,null);
if(selfValue!=toValue&(selfValue==null | | |!selfValue.Equals(toValue)))
返回false;
}
}
}
返回true;
}
返回AObj==BObj;
}
只是这会失败,因为当递归调用AllPublicPropertiesEqual时,我需要传递特定的值类型,而不仅仅是泛型对象类型。
但是我不知道怎么做。。。。非常感谢您的任何想法……您的方法不必是通用的。您可以将方法的开头更改为:
public static bool AllPublicPropertiesEqual(object AObj, object BObj, params string[] ignore)
{
if (AObj != null && BObj != null)
{
Type type = AObj.GetType();
if (BObj.GetType() != type)
throw new Exception("Objects should be of the same type");
....
}
....
}
您的方法不必是泛型的。您可以将方法的开头更改为:
public static bool AllPublicPropertiesEqual(object AObj, object BObj, params string[] ignore)
{
if (AObj != null && BObj != null)
{
Type type = AObj.GetType();
if (BObj.GetType() != type)
throw new Exception("Objects should be of the same type");
....
}
....
}
首先,你们应该为这些类创建接口,因为我看到你们可以组合这些类,但它们都有相同的属性。第二个选项是使用这些属性创建一些基本抽象类并从中继承。选择什么取决于你自己。 与在这个基类或接口Equals函数中创建直接等于共享属性的函数相比,它更容易,而且我认为效率更高:-) 然后,您可以使用这个类,在BasicStaff实现等于方法中创建BasicStaff类和AllTheStaff类,如下所示
public override bool Equals(BaseStaff staff) {
this.anInt == staff.anInt &&
this.aBool == staff.aBool;
}
在所有的staff中,你都可以像这样覆盖这个方法
public override bool Equals(BaseStaff staff) {
bool baseEquals = base.Equals(staff);
bool basicStaffEquals = this.BasicStaff.Equals(staff);
return baseEquals || basicStaffEquals;
}
这只是一个核心想法,也许我不太了解您真正想要实现的目标,但希望它能帮助您:)首先,您应该为这些类创建接口,因为根据我的了解,您可以组合这些类,但它们都具有相同的属性。第二个选项是使用这些属性创建一些基本抽象类并从中继承。选择什么取决于你自己。 与在这个基类或接口Equals函数中创建直接等于共享属性的函数相比,它更容易,而且我认为效率更高:-) 然后,您可以使用这个类,在BasicStaff实现等于方法中创建BasicStaff类和AllTheStaff类,如下所示
public override bool Equals(BaseStaff staff) {
this.anInt == staff.anInt &&
this.aBool == staff.aBool;
}
在所有的staff中,你都可以像这样覆盖这个方法
public override bool Equals(BaseStaff staff) {
bool baseEquals = base.Equals(staff);
bool basicStaffEquals = this.BasicStaff.Equals(staff);
return baseEquals || basicStaffEquals;
}
这只是一个核心想法,也许我不太了解您真正想要实现的目标,但希望它能帮助您:)测试解决方案
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetCType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object aElementValues = (type.GetProperty(pInfo.Name).GetValue(AObj, null));
object bElementValues = (type.GetProperty(pInfo.Name).GetValue(BObj, null));
if (aElementValues != null && bElementValues != null)
{
List<object> AListValues = new List<object>();
List<object> BListValues = new List<object>();
foreach (var v in (IEnumerable)aElementValues)
AListValues.Add(v);
foreach (var v in (IEnumerable)bElementValues)
BListValues.Add(v);
if (AListValues.Count == BListValues.Count)
{
object[] aArray = AListValues.ToArray();
object[] bArray = BListValues.ToArray();
for (int i = 0; i < aArray.Length; i++)
{
if (!AllPublicPropertiesEqual(aArray[i], bArray[i]))
return false;
}
}
else
return false;
}
else if ((aElementValues == null) != (bElementValues == null))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AObjectValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BObjectValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual(BObjectValue, AObjectValue))
return false;
}
else
{
object aValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object bValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (aValue != bValue && (aValue == null || !aValue.Equals(bValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
}
public static bool AllPublicPropertiesEqual(T AObj,T BObj,params string[]ignore),其中T:class
{
if(AObj!=null&&BObj!=null)
{
类型=类型(T);
列表忽略列表=新列表(忽略);
foreach(type.GetCType().GetProperties(BindingFlags.Public | BindingFlags.Instance)中的PropertyInfo-pInfo)
{
如果(!ignoreList.Contains(pInfo.Name))
{
if(pInfo.PropertyType.IsArray)
{
对象aElementValues=(type.GetProperty(pInfo.Name).GetValue(AObj,null));
对象bElementValues=(type.GetProperty(pInfo.Name).GetValue(BObj,null));
if(aElementValues!=null&&bElementValues!=null)
{
List AListValues=新列表();
List BListValues=新列表();
foreach(变量v在(IEnumerable)aElementValues中)
增加(v);
foreach(在(IEnumerable)BelementValue中的var v)
BListValues.Add(v);
if(AListValues.Count==BListValues.Count)
{