在List提供的方法中,提供了将一个类型的List转换成为另一个List类型的方法,如下:
//构造类1集合 TestClass1 test1 = new TestClass1(); List<TestClass1> class1 = new List<TestClass1>(); test1 .Name ="lhc"; test1 .ID =2; class1.Add(test1); //构造类2集合 TestClass2 test2 = new TestClass2(); List<TestClass2> class2 = new List<TestClass2>(); class2.Add(test2); //两个集合相互转换 class2 = class1.ConvertAll<TestClass2>(new Converter<TestClass1, TestClass2>(c1 => new TestClass2() { Name=c1.Name}));//convert里面指定转换规则
如上代码:利用List的ConvertAll方法,可以将两种类型的集合进行相互转换,但是要自己在Converter的构造放中,定义转换规则,如上代码中的转换规则为一个Lambda表达式,指定了将属性的对应关系。
这种方法实用性比较普遍,但是,对于特殊的情况,比如,在WCF中,我定义的数据契约和Model层实体的属性名称是一致的,这时候,如果我们手动写这个转换规则的话,就非常麻烦了,在这里,我们扔掉这个方法,利用泛型手动写一个通用的方法:
#region 两个集合转换过程 public static List<M> ListInputToOutput<T, M>(List<T> objTlist) where T : new() where M : new() { //定义返回的集合 List<M> ListM = new List<M>(); //定义临时M类变量 M TempM = new M(); foreach (T item in objTlist) { TempM = InputToOutput<T, M>(item); ListM.Add(TempM);//加入结果集合 } return ListM; } #endregion #region 单个实体转换过程 //转换规则 //T代表要待转换的对象 //M代表转换后的对象 //参数中传入被转换的对象 public static M InputToOutput<T, M>(T ObjT) where T : new() where M : new() // where M:ICollection<M> { string tempName = string.Empty; //临时保存属性名称 //获取T的所有属性和值 //T t = new T(); M Result = new M(); //定义返回值 PropertyInfo[] propertys = Result.GetType().GetProperties(); //循环获取T的属性及其值 foreach (PropertyInfo pr in propertys) { tempName = pr.Name;//将属性名称赋值给临时变量 PropertyInfo findPro = ObjT.GetType().GetProperty(tempName);//从带转换实体获取属性 if (findPro != null) //如果获取到了:尝试执行赋值过程 { if (!pr.CanWrite) continue; //如果属性不可写,跳出 //取值:参数不匹配------------- object value = findPro.GetValue(ObjT, null); //如果为非空,则赋值给对象的属性 if (value != DBNull.Value) pr.SetValue(Result, value, null); } } return Result; } #endregion
这段代码具体思路是:获取M实体的属性集合,然后去T的属性里面去找,如果T内含有此属性,那么,就将T的此属性值赋值给M的这个属性,如果没有就略过。
动态获取属性值的过程感觉见的很多了,但是尤其要注意的是where约束条件这部分,因为泛型毕竟是动态编译的时候才会确定类型,但是在代码中可能用到类型的一些属性方法,在这种情况下,就必须添加约束条件了。