我有个public class A
{
public int AID{get;set;}
public IList<B> BList{get;set;}
}
public class B
{
public int BID{get;set;}
public IList<C> CList{get;set;}
}public class C
{
public int CID{get;set;}
}static void Main(string[] args)
{
IList<A> aList = new List<A>();
aList.Add(new A { AID = 1, BList = new List<B>() { new B{BID=1}} });
aList.Add(new A { AID = 2, BList = new List<B>() { new B { BID = 2 } } });
EqualityComparer<A> eq = new EqualityComparer<A>();
//eq.ComparerString.Add("AID");
eq.ComparerString.Add("BList");
bool isExists = aList.Contains(new A { BList = new List<B>() { new B { BID = 1 } } }, eq);
Console.WriteLine(isExists);
}然后 有个比较类
public class EqualityComparer<T> : IEqualityComparer<T>
{
/// <summary>
/// 需要比较的属性名称
/// </summary>
public IList<string> ComparerString
{
get;
set;
} public EqualityComparer()
{
ComparerString = new List<string>();
} public bool Equals(T a, T b)
{
if (object.ReferenceEquals(a, b))
return true;
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null))
return false;
if (ComparerString == null || ComparerString.Count <= 0)
{
bool isSame = false;
foreach (PropertyInfo p in a.GetType().GetProperties())
{
if (p.PropertyType.IsGenericType)
{
if (!IsListSame(p.GetValue(a, null), b.GetType().GetProperty(p.Name).GetValue(b, null)))
return false;
}
else
{
isSame = p.GetValue(a, null) == b.GetType().GetProperty(p.Name).GetValue(b, null);
if (!isSame)
return false;
}
}
return true;
}
else
{
foreach (string str in ComparerString)
{
if (a.GetType().GetProperty(str).PropertyType.IsGenericType)
{
if (!IsListSame(a.GetType().GetProperty(str).GetValue(a, null), b.GetType().GetProperty(str).GetValue(b, null)))
return false;
}
else
{
if (a.GetType().GetProperty(str).GetValue(a, null) != b.GetType().GetProperty(str).GetValue(b, null))
return false;
}
}
return true;
}
} private bool IsListSame(object oa,object ob)////这个比较IList 怎么比较 不知道类型 怎么弄?
{
IList<object> a=new List<object>();
IList<object> b = new List<object>(); foreach (object suba in a)
{
if (b.Contains(suba))
return true;
}
return false;
} public int GetHashCode(T o)
{
if (object.ReferenceEquals(o, null))
return 0;
int hashResult = 0;
if (ComparerString == null || ComparerString.Count <= 0)
{
foreach (PropertyInfo p in o.GetType().GetProperties())
{
hashResult = hashResult ^ (p.GetValue(o, null) != null ? p.GetValue(o, null).GetHashCode() : 0);
}
return hashResult;
}
else
{
foreach (string str in ComparerString)
{
hashResult = hashResult ^ (o.GetType().GetProperty(str).GetValue(o, null) != null ? o.GetType().GetProperty(str).GetValue(o, null).GetHashCode() : 0);
}
return hashResult;
}
}
}
但是问题就卡在了IList类型的属性怎么比较 反射怎么弄?
不会
求各位大神讲解
{
public int AID{get;set;}
public IList<B> BList{get;set;}
}
public class B
{
public int BID{get;set;}
public IList<C> CList{get;set;}
}public class C
{
public int CID{get;set;}
}static void Main(string[] args)
{
IList<A> aList = new List<A>();
aList.Add(new A { AID = 1, BList = new List<B>() { new B{BID=1}} });
aList.Add(new A { AID = 2, BList = new List<B>() { new B { BID = 2 } } });
EqualityComparer<A> eq = new EqualityComparer<A>();
//eq.ComparerString.Add("AID");
eq.ComparerString.Add("BList");
bool isExists = aList.Contains(new A { BList = new List<B>() { new B { BID = 1 } } }, eq);
Console.WriteLine(isExists);
}然后 有个比较类
public class EqualityComparer<T> : IEqualityComparer<T>
{
/// <summary>
/// 需要比较的属性名称
/// </summary>
public IList<string> ComparerString
{
get;
set;
} public EqualityComparer()
{
ComparerString = new List<string>();
} public bool Equals(T a, T b)
{
if (object.ReferenceEquals(a, b))
return true;
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null))
return false;
if (ComparerString == null || ComparerString.Count <= 0)
{
bool isSame = false;
foreach (PropertyInfo p in a.GetType().GetProperties())
{
if (p.PropertyType.IsGenericType)
{
if (!IsListSame(p.GetValue(a, null), b.GetType().GetProperty(p.Name).GetValue(b, null)))
return false;
}
else
{
isSame = p.GetValue(a, null) == b.GetType().GetProperty(p.Name).GetValue(b, null);
if (!isSame)
return false;
}
}
return true;
}
else
{
foreach (string str in ComparerString)
{
if (a.GetType().GetProperty(str).PropertyType.IsGenericType)
{
if (!IsListSame(a.GetType().GetProperty(str).GetValue(a, null), b.GetType().GetProperty(str).GetValue(b, null)))
return false;
}
else
{
if (a.GetType().GetProperty(str).GetValue(a, null) != b.GetType().GetProperty(str).GetValue(b, null))
return false;
}
}
return true;
}
} private bool IsListSame(object oa,object ob)////这个比较IList 怎么比较 不知道类型 怎么弄?
{
IList<object> a=new List<object>();
IList<object> b = new List<object>(); foreach (object suba in a)
{
if (b.Contains(suba))
return true;
}
return false;
} public int GetHashCode(T o)
{
if (object.ReferenceEquals(o, null))
return 0;
int hashResult = 0;
if (ComparerString == null || ComparerString.Count <= 0)
{
foreach (PropertyInfo p in o.GetType().GetProperties())
{
hashResult = hashResult ^ (p.GetValue(o, null) != null ? p.GetValue(o, null).GetHashCode() : 0);
}
return hashResult;
}
else
{
foreach (string str in ComparerString)
{
hashResult = hashResult ^ (o.GetType().GetProperty(str).GetValue(o, null) != null ? o.GetType().GetProperty(str).GetValue(o, null).GetHashCode() : 0);
}
return hashResult;
}
}
}
但是问题就卡在了IList类型的属性怎么比较 反射怎么弄?
不会
求各位大神讲解
{
IList<object> a=new List<object>();
IList<object> b = new List<object>(); foreach (object suba in a)
{
if (b.Contains(suba))
return true;
}
return false;
}
这个方法和你其他的那些代码没有看出来有什么关系。
2个参数没看出来有什么用。
不需要考虑b的泛型属性吗?你写个抽象类,它里面重写object.Equals()方法
这个方法只是比较IList的方法 oa为一个IList反射的值 ob是要比较的IList反射的值
还有 我是比较对象下面的IList属性 下面还有子对象 如果只是单纯的IList 可以用Equals()比较
所以用到了反射
我就是想写个可以兼容多种类型 情况下的对象比较
所以用到了反射
我就是想写个可以兼容多种类型 情况下的对象比较
public class EqualityComparer<T> : IEqualityComparer<T> where T : A
{
public bool Equals(T x, T y)
{
if (x == null)
{
if (y == null)
return true;
else
return false;
}
else
{
if (y == null)
return false;
else
{
if (x.AID != y.AID)
return false;
else if (x.BList == null)
{
if (y.BList == null)
return true;
else
return false;
}
else
{
if (y.BList == null)
return false;
else
{
if (x.BList.Count != y.BList.Count)
return false;
else
{
for (int i = x.BList.Count - 1; i >= 0; i--)
{
if (x.BList[i].BID != y.BList[i].BID)
return false;
else if (x.BList[i].CList == null)
{
if (y.BList[i].CList == null)
return true;
else
return false;
}
else
{
if (y.BList[i].CList == null)
return false;
else
{
if (x.BList[i].CList.Count != y.BList[i].CList.Count)
return false;
else
{
for (int j = x.BList[i].CList.Count - 1; j >= 0; j--)
{
if (x.BList[i].CList[j].CID != y.BList[i].CList[j].CID)
return false;
}
}
}
}
}
}
}
}
}
}
return true;
} public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
}
你这样我知道
我的目的是利用反射去比较 因为你所比较的对象的不确定性 遇到IList就很麻烦
所以问题现在就卡在这里了
利用反射 比较IList是否相等
你这样我知道
我的目的是利用反射去比较 因为你所比较的对象的不确定性 遇到IList就很麻烦
所以问题现在就卡在这里了
利用反射 比较IList是否相等
获取泛型的参数,通过如下方法可获得:
_List.GetType().GetGenericArguments()
如果只有一个泛型参数,这个返回的数组长度就是1,如果不是泛型类型,这个返回的数组长度为0.
然后比较这个泛型类型是否相等,相等则继续比较泛型的属性值。
比较IList内部的元素时,先判断是否是IList,如果是,强制类型转换到接口IList,调用接口方法获取长度比较,如果长度相同,然后比较每个Item元素的类型,如果类型相同,再判断是否为结构体,结构体直接比较值,如果是类,比较内部属性。不嵌套想起来就头大了,你再嵌套就更加不敢想了(没那么多时间)。
能给点代码提示一下吗?
谢谢了!
foreach (PropertyInfo p in a.GetType().GetProperties())
----------
a下面的BList
但是p是属性对象没办法通过索引获得到List里面的值
{
var obj = p.GetValue(a, null);
if (obj is IList)
{
//转换为IList比较内部项
IList lobj = (IList)obj;
for (int i = lobj.Count - 1; i >= 0; i--)
{
var item = lobj[i];//得到内部项,怎么比较自己写
}
}
else
{
//常规比较
}
我正好想到了 把(IList)p.GetValue(a,null)就可以了
不过还是要说声谢谢
我只是想用反射解决掉对象的不确定性
我比较喜欢用反射
呵呵!
因为我现在遇到了这样的问题
有多个类型的对象,要比较对象中的Name属性的值是否存在(如果还有其他的属性要求比较的话)
所以我用到了IEqualityComparer<T>
和要比较对象的类型的不确定性和属性的不确定性
所以才会用到反射去解决问题
本人还是觉得用反射可以灵活的解决掉问题
不想写那么多重复的代码
谢谢大家!
这个事可以获得到IList的值
但是是个object的值
我把它转成IList的就是一个集合了
可以通过索引去取得到里面的值
这个事可以获得到IList的值
但是是个object的值
我把它转成IList的就是一个集合了
可以通过索引去取得到里面的值
只是简单的比较,我觉得这样子时没有问题的
如果你要那样写,我只会感觉代码的冗余
再说我写这个的前提只是在一个IList集合里面判断有没有指定条件重复的对象
如果你想判断其他的 A类型对象和B类型对象去比较的话 可以去做相应的变通
没有必要吧相同结构的代码重复写上个七八遍
没有什么意思
还有使用反射现在也大多是简单的比较和获取 太复杂的却是消耗性能而不是那么好写的
做最简单的比较我觉得还是可以使用的
{
public int AID{get;set;}
public IList<B> BList{get;set;}
}
public class B
{
public int BID{get;set;}
public IList<C> CList{get;set;}
}
加下面这些应该可以了
public class A1
{
public int AID{get;set;}
public B[] BList{get;set;}
}
public class B1
{
public int BID{get;set;}
public [] CList{get;set;}
}