问题描述
我有个publicclassA{publicintAID{get;set;}publicIList<B>BList{get;set;}}publicclassB{publicintBID{get;set;}publicIList<C>CList{get;set;}}publicclassC{publicintCID{get;set;}}staticvoidMain(string[]args){IList<A>aList=newList<A>();aList.Add(newA{AID=1,BList=newList<B>(){newB{BID=1}}});aList.Add(newA{AID=2,BList=newList<B>(){newB{BID=2}}});EqualityComparer<A>eq=newEqualityComparer<A>();//eq.ComparerString.Add("AID");eq.ComparerString.Add("BList");boolisExists=aList.Contains(newA{BList=newList<B>(){newB{BID=1}}},eq);Console.WriteLine(isExists);}然后有个比较类publicclassEqualityComparer<T>:IEqualityComparer<T>{///<summary>///需要比较的属性名称///</summary>publicIList<string>ComparerString{get;set;}publicEqualityComparer(){ComparerString=newList<string>();}publicboolEquals(Ta,Tb){if(object.ReferenceEquals(a,b))returntrue;if(object.ReferenceEquals(a,null)||object.ReferenceEquals(b,null))returnfalse;if(ComparerString==null||ComparerString.Count<=0){boolisSame=false;foreach(PropertyInfopina.GetType().GetProperties()){if(p.PropertyType.IsGenericType){if(!IsListSame(p.GetValue(a,null),b.GetType().GetProperty(p.Name).GetValue(b,null)))returnfalse;}else{isSame=p.GetValue(a,null)==b.GetType().GetProperty(p.Name).GetValue(b,null);if(!isSame)returnfalse;}}returntrue;}else{foreach(stringstrinComparerString){if(a.GetType().GetProperty(str).PropertyType.IsGenericType){if(!IsListSame(a.GetType().GetProperty(str).GetValue(a,null),b.GetType().GetProperty(str).GetValue(b,null)))returnfalse;}else{if(a.GetType().GetProperty(str).GetValue(a,null)!=b.GetType().GetProperty(str).GetValue(b,null))returnfalse;}}returntrue;}}privateboolIsListSame(objectoa,objectob)////这个比较IList怎么比较不知道类型怎么弄?{IList<object>a=newList<object>();IList<object>b=newList<object>();foreach(objectsubaina){if(b.Contains(suba))returntrue;}returnfalse;}publicintGetHashCode(To){if(object.ReferenceEquals(o,null))return0;inthashResult=0;if(ComparerString==null||ComparerString.Count<=0){foreach(PropertyInfopino.GetType().GetProperties()){hashResult=hashResult^(p.GetValue(o,null)!=null?p.GetValue(o,null).GetHashCode():0);}returnhashResult;}else{foreach(stringstrinComparerString){hashResult=hashResult^(o.GetType().GetProperty(str).GetValue(o,null)!=null?o.GetType().GetProperty(str).GetValue(o,null).GetHashCode():0);}returnhashResult;}}}
但是问题就卡在了IList类型的属性怎么比较反射怎么弄?不会求各位大神讲解
解决方案
解决方案二:
privateboolIsListSame(objectoa,objectob)////这个比较IList怎么比较不知道类型怎么弄?{IList<object>a=newList<object>();IList<object>b=newList<object>();foreach(objectsubaina){if(b.Contains(suba))returntrue;}returnfalse;}这个方法和你其他的那些代码没有看出来有什么关系。2个参数没看出来有什么用。
解决方案三:
好长啊,头晕
解决方案四:
很长!很长!
解决方案五:
if(a.GetType().GetProperty(str).PropertyType.IsGenericType)不需要考虑b的泛型属性吗?你写个抽象类,它里面重写object.Equals()方法
解决方案六:
引用1楼ronegl的回复:
privateboolIsListSame(objectoa,objectob)////这个比较IList怎么比较不知道类型怎么弄?{IList<object>a=newList<object>();IList<object>b=newList<object>();foreach(objectsubaina)……
这个方法只是比较IList的方法oa为一个IList反射的值ob是要比较的IList反射的值还有我是比较对象下面的IList属性下面还有子对象如果只是单纯的IList可以用Equals()比较
解决方案七:
还有请看清楚我想通过BList这个属性来比较所以用到了反射我就是想写个可以兼容多种类型情况下的对象比较
解决方案八:
还有请看清楚我想通过BList这个属性来比较所以用到了反射我就是想写个可以兼容多种类型情况下的对象比较
解决方案九:
求解!!!!
解决方案十:
求解!!!!
解决方案十一:
把关键代码贴上就行了太长没时间看呀
解决方案十二:
这就是关键代码啊,也不长就是想知道怎么样利用反射比较对象的IList属性值
解决方案十三:
求解!!!!
解决方案十四:
求大神们求解帮忙看看
解决方案十五:
反射到底是做什么的--我还真没接触到过--他在项目中有什么好处?
解决方案:
其实我个人觉得反射的作用还是挺大的它提供了不确定性的获取和设置很值得一用的求解!!!
解决方案:
那位大神能帮忙解决下解决完我会追加分的
解决方案:
求大神帮忙解决谢谢啦解决完我马上追加分!
解决方案:
分数已追加,求大神帮忙解决谢谢啦
解决方案:
分数已追加,求大神帮忙解决谢谢啦
解决方案:
难道没人知道怎么做吗?大神大侠们。。。。。。。。。。
解决方案:
都没人回答啊。。。哎
解决方案:
都没人回答啊。。。哎
解决方案:
都没人回答啊。。。哎
解决方案:
求指教啊,不能沉啊。。
解决方案:
你的IList的比较真麻烦,嵌套太深,这样效率也很低,建议你使用Struct来代替Class,那样比较的就不会引用地址而是值本身。publicclassEqualityComparer<T>:IEqualityComparer<T>whereT:A{publicboolEquals(Tx,Ty){if(x==null){if(y==null)returntrue;elsereturnfalse;}else{if(y==null)returnfalse;else{if(x.AID!=y.AID)returnfalse;elseif(x.BList==null){if(y.BList==null)returntrue;elsereturnfalse;}else{if(y.BList==null)returnfalse;else{if(x.BList.Count!=y.BList.Count)returnfalse;else{for(inti=x.BList.Count-1;i>=0;i--){if(x.BList[i].BID!=y.BList[i].BID)returnfalse;elseif(x.BList[i].CList==null){if(y.BList[i].CList==null)returntrue;elsereturnfalse;}else{if(y.BList[i].CList==null)returnfalse;else{if(x.BList[i].CList.Count!=y.BList[i].CList.Count)returnfalse;else{for(intj=x.BList[i].CList.Count-1;j>=0;j--){if(x.BList[i].CList[j].CID!=y.BList[i].CList[j].CID)returnfalse;}}}}}}}}}}returntrue;}publicintGetHashCode(Tobj){returnobj.GetHashCode();}}
解决方案:
谢谢!你这样我知道我的目的是利用反射去比较因为你所比较的对象的不确定性遇到IList就很麻烦所以问题现在就卡在这里了利用反射比较IList是否相等
解决方案:
谢谢!你这样我知道我的目的是利用反射去比较因为你所比较的对象的不确定性遇到IList就很麻烦所以问题现在就卡在这里了利用反射比较IList是否相等
解决方案:
如果你的IList没有嵌套,我愿意帮你写反射的过程,但是嵌套了反射实在头大,我这里只能给你点建议性的方案。获取泛型的参数,通过如下方法可获得:_List.GetType().GetGenericArguments()如果只有一个泛型参数,这个返回的数组长度就是1,如果不是泛型类型,这个返回的数组长度为0.然后比较这个泛型类型是否相等,相等则继续比较泛型的属性值。比较IList内部的元素时,先判断是否是IList,如果是,强制类型转换到接口IList,调用接口方法获取长度比较,如果长度相同,然后比较每个Item元素的类型,如果类型相同,再判断是否为结构体,结构体直接比较值,如果是类,比较内部属性。不嵌套想起来就头大了,你再嵌套就更加不敢想了(没那么多时间)。
解决方案:
还有一个方法,用JSON序列化后,比较序列化后的字符串是否相等,前提是你设计的类型必须可序列化,私有成员不能参与比较。另外[DataContract]标记别用在IList上面,否则对IList的序列化行为会发生改变。
解决方案:
谢谢!我看看
解决方案:
我现在不知道怎么样比较IList的泛型类型和它里面的值能给点代码提示一下吗?谢谢了!
解决方案:
我不是说了吗?如果是IList的对象,只要用索引访问器访问就可以得到内部值了,例如_List[0]将得到里面第一个项的值,它的类型是_List.GetType().GetGenericArguments()[0],当然,如果你的是IList<Object>,那么比较类型意义不大,直接通过这个项的值反射类型比较更好。
解决方案:
我是循环a的属性来的啊foreach(PropertyInfopina.GetType().GetProperties())----------a下面的BList但是p是属性对象没办法通过索引获得到List里面的值
解决方案:
foreach(PropertyInfopina.GetType().GetProperties()){varobj=p.GetValue(a,null);if(objisIList){//转换为IList比较内部项IListlobj=(IList)obj;for(inti=lobj.Count-1;i>=0;i--){varitem=lobj[i];//得到内部项,怎么比较自己写}}else{//常规比较}
解决方案:
额,我只能说你在玩一个不应该玩的动作IEqualityComparer<T>本身就是一个场合性的东西,也就是说他本来就应该和上下文关联的东西,而非通用滴玩意,请自己想一下微软为啥要重载出这么一个方法让你自己提供IEqualityComparer<T>,很明显就是微软说我不知道你要干啥,这不是通用标准,我做不出来。请你自己根据上下文实现。所以你企图用一个通用的玩意去包装的思维就和本身微软的思路是冲突滴,要能通用的化,微软何必要重载出这个方法给你呢??
解决方案:
引用34楼的回复:
C#codeforeach(PropertyInfopina.GetType().GetProperties()){varobj=p.GetValue(a,null);if(objisIList){……
在你发这之前我正好想到了把(IList)p.GetValue(a,null)就可以了不过还是要说声谢谢我只是想用反射解决掉对象的不确定性我比较喜欢用反射呵呵!
解决方案:
还有为什么要这样写的问题因为我现在遇到了这样的问题有多个类型的对象,要比较对象中的Name属性的值是否存在(如果还有其他的属性要求比较的话)所以我用到了IEqualityComparer<T>和要比较对象的类型的不确定性和属性的不确定性所以才会用到反射去解决问题本人还是觉得用反射可以灵活的解决掉问题不想写那么多重复的代码谢谢大家!
解决方案:
IList内部有那么一个属性,名字未知,默认叫“Items”,你可以反射后遍历看看是否存在这样的属性,该属性是索引器,可以用索引来访问内部元素,如果要反射该属性的值,p.GetValue(a,null)是不行的,第二个参数这时就需要用到了,例如获取第一个项,_List[0],通过反射就是p.GetValue(a,newObject[]{0}),这里的p是索引化属性,那个a则是_List。
解决方案:
p.GetValue(a,null)这个事可以获得到IList的值但是是个object的值我把它转成IList的就是一个集合了可以通过索引去取得到里面的值
解决方案:
p.GetValue(a,null)这个事可以获得到IList的值但是是个object的值我把它转成IList的就是一个集合了可以通过索引去取得到里面的值
解决方案:
1.反射写的越多,说明结构设计的越不合理。尽量避免使用反射才是正常的设计。2.反射的性能损耗我想不用说你也明白。
解决方案:
不是结构设计的合不合理的问题有的时候是免不了的再说反射虽然是很消耗性能但是只要不是太深的反射式没有问题的很简单的反射获得数据比你写N个方法来的实际
解决方案:
有多个类型的对象,要比较对象中的Name属性的值是否存在(如果还有其他的属性要求比较的话)==============我只能告诉你在你费劲巴拉的搞这个通用解的时候我的要求不是检查name值是否一样。我告诉你对象A.name和对象B.username比较或者我要A.firstName+A.lastName和B.Name比较现在你还觉着你封装这块有通用性吗?ps:别过渡封装,别需求镀金。其实我们大多数人都很想把自己以前的过度封装的类全部砸了,因为他根本就是错误的封装方式
解决方案:
引用43楼的回复:
有多个类型的对象,要比较对象中的Name属性的值是否存在(如果还有其他的属性要求比较的话)==============我只能告诉你在你费劲巴拉的搞这个通用解的时候我的要求不是检查name值是否一样。我告诉你对象A.name和对象B.username比较或者我要A.firstName+A.lastName和B.Name比较现在你还觉着你封装这块有通用性……
他是在学习怎么玩反射,而不是在设计通用方法。
解决方案:
一样可以的啊只不过是需要做下变通而已只是简单的比较,我觉得这样子时没有问题的如果你要那样写,我只会感觉代码的冗余再说我写这个的前提只是在一个IList集合里面判断有没有指定条件重复的对象如果你想判断其他的A类型对象和B类型对象去比较的话可以去做相应的变通没有必要吧相同结构的代码重复写上个七八遍没有什么意思还有使用反射现在也大多是简单的比较和获取太复杂的却是消耗性能而不是那么好写的做最简单的比较我觉得还是可以使用的
解决方案:
该回复于2012-04-01 13:22:23被版主删除
解决方案:
这个代码写的不错,刚刚也在看反射,只能看懂,运用还不是很熟练的。
解决方案:
我只是觉得用反射做这种简单的获取赋值比较会比较方便代码的重用性比较高
解决方案:
publicclassA{publicintAID{get;set;}publicIList<B>BList{get;set;}}publicclassB{publicintBID{get;set;}publicIList<C>CList{get;set;}}加下面这些应该可以了publicclassA1{publicintAID{get;set;}publicB[]BList{get;set;}}publicclassB1{publicintBID{get;set;}public[]CList{get;set;}}
解决方案:
数组有一定的局限性泛型比数组好用