有时候,需要把一个类的相同名称的字段、属性相互赋值,难道要一句一句代码的写?在数据库操作的模型中,视图模型和表模型有一定的字段是同名的,很多时候可能需要从视图模型复制到表模型,或者反过来。。。
重复劳动是比较郁闷,我又比较懒。所以写了个转换器:
001 | using System; |
002 | using System.Collections.Generic; |
003 | using System.Linq; |
004 | using System.Web; |
005 | using System.Reflection; |
006 | using System.Collections; |
007 |
008 | namespace com.hetaoos.Common.Utils |
009 | { |
010 | /// <summary> |
011 | /// 类属性/字段的值复制工具 |
012 | /// </summary> |
013 | public class ClassValueCopier |
014 | { |
015 | /// <summary> |
016 | /// 复制 |
017 | /// </summary> |
018 | /// <param name="destination">目标</param> |
019 | /// <param name="source">来源</param> |
020 | /// <returns>成功复制的值个数</returns> |
021 | public static int Copy( object destination, object source) |
022 | { |
023 | if (destination == null || source == null ) |
024 | { |
025 | return 0; |
026 | } |
027 | return Copy(destination, source, source.GetType()); |
028 | } |
029 |
030 | /// <summary> |
031 | /// 复制 |
032 | /// </summary> |
033 | /// <param name="destination">目标</param> |
034 | /// <param name="source">来源</param> |
035 | /// <param name="type">复制的属性字段模板</param> |
036 | /// <returns>成功复制的值个数</returns> |
037 | public static int Copy( object destination, object source, Type type) |
038 | { |
039 | return Copy(destination, source, type, null ); |
040 | } |
041 |
042 | /// <summary> |
043 | /// 复制 |
044 | /// </summary> |
045 | /// <param name="destination">目标</param> |
046 | /// <param name="source">来源</param> |
047 | /// <param name="type">复制的属性字段模板</param> |
048 | /// <param name="excludeName">排除下列名称的属性不要复制</param> |
049 | /// <returns>成功复制的值个数</returns> |
050 | public static int Copy( object destination, object source, Type type, IEnumerable< string > excludeName) |
051 | { |
052 | if (destination == null || source == null ) |
053 | { |
054 | return 0; |
055 | } |
056 | if (excludeName == null ) |
057 | { |
058 | excludeName = new List< string >(); |
059 | } |
060 | int i = 0; |
061 | Type desType = destination.GetType(); |
062 | foreach (FieldInfo mi in type.GetFields()) |
063 | { |
064 | if (excludeName.Contains(mi.Name)) |
065 | { |
066 | continue ; |
067 | } |
068 | try |
069 | { |
070 | FieldInfo des = desType.GetField(mi.Name); |
071 | if (des != null && des.FieldType == mi.FieldType) |
072 | { |
073 | des.SetValue(destination, mi.GetValue(source)); |
074 | i++; |
075 | } |
076 |
077 | } |
078 | catch |
079 | { |
080 | } |
081 | } |
082 |
083 |
084 | foreach (PropertyInfo pi in type.GetProperties()) |
085 | { |
086 | if (excludeName.Contains(pi.Name)) |
087 | { |
088 | continue ; |
089 | } |
090 | try |
091 | { |
092 | PropertyInfo des = desType.GetProperty(pi.Name); |
093 | if (des != null && des.PropertyType == pi.PropertyType && des.CanWrite && pi.CanRead) |
094 | { |
095 | des.SetValue(destination, pi.GetValue(source, null ), null ); |
096 | i++; |
097 | } |
098 |
099 | } |
100 | catch |
101 | { |
102 | //throw ex; |
103 | } |
104 | } |
105 | return i; |
106 | } |
107 | } |
108 |
109 | #region 扩展方法 For .NET 3.0+ |
110 | /// <summary> |
111 | /// 类属性/字段的值复制工具 扩展方法 |
112 | /// </summary> |
113 | public static class ClassValueCopier2 |
114 | { |
115 | /// <summary> |
116 | /// 获取实体类的属性名称 |
117 | /// </summary> |
118 | /// <param name="source">实体类</param> |
119 | /// <returns>属性名称列表</returns> |
120 | public static List< string > GetPropertyNames( this object source) |
121 | { |
122 | if (source == null ) |
123 | { |
124 | return new List< string >(); |
125 | } |
126 | return GetPropertyNames(source.GetType()); |
127 | } |
128 | /// <summary> |
129 | /// 获取类类型的属性名称(按声明顺序) |
130 | /// </summary> |
131 | /// <param name="source">类类型</param> |
132 | /// <returns>属性名称列表</returns> |
133 | public static List< string > GetPropertyNames( this Type source) |
134 | { |
135 | return GetPropertyNames(source, true ); |
136 | } |
137 | /// <summary> |
138 | /// 获取类类型的属性名称 |
139 | /// </summary> |
140 | /// <param name="source">类类型</param> |
141 | /// <param name="declarationOrder">是否按声明顺序排序</param> |
142 | /// <returns>属性名称列表</returns> |
143 | public static List< string > GetPropertyNames( this Type source, bool declarationOrder) |
144 | { |
145 | if (source == null ) |
146 | { |
147 | return new List< string >(); |
148 | } |
149 | var list = source.GetProperties().AsQueryable(); |
150 | if (declarationOrder) |
151 | { |
152 | list = list.OrderBy(p => p.MetadataToken); |
153 | } |
154 | return list.Select(o => o.Name).ToList(); ; |
155 | } |
156 |
157 | /// <summary> |
158 | /// 从源对象赋值到当前对象 |
159 | /// </summary> |
160 | /// <param name="destination">当前对象</param> |
161 | /// <param name="source">源对象</param> |
162 | /// <returns>成功复制的值个数</returns> |
163 | public static int CopyValueFrom( this object destination, object source) |
164 | { |
165 | return CopyValueFrom(destination, source, null ); |
166 | } |
167 |
168 | /// <summary> |
169 | /// 从源对象赋值到当前对象 |
170 | /// </summary> |
171 | /// <param name="destination">当前对象</param> |
172 | /// <param name="source">源对象</param> |
173 | /// <param name="excludeName">排除下列名称的属性不要复制</param> |
174 | /// <returns>成功复制的值个数</returns> |
175 | public static int CopyValueFrom( this object destination, object source, IEnumerable< string > excludeName) |
176 | { |
177 | if (destination == null || source == null ) |
178 | { |
179 | return 0; |
180 | } |
181 | return ClassValueCopier.Copy(destination, source, source.GetType(), excludeName); |
182 | } |
183 |
184 | /// <summary> |
185 | /// 从当前对象赋值到目标对象 |
186 | /// </summary> |
187 | /// <param name="source">当前对象</param> |
188 | /// <param name="destination">目标对象</param> |
189 | /// <returns>成功复制的值个数</returns> |
190 | public static int CopyValueTo( this object source, object destination) |
191 | { |
192 | return CopyValueTo(destination, source, null ); |
193 | } |
194 |
195 | /// <summary> |
196 | /// 从当前对象赋值到目标对象 |
197 | /// </summary> |
198 | /// <param name="source">当前对象</param> |
199 | /// <param name="destination">目标对象</param> |
200 | /// <param name="excludeName">排除下列名称的属性不要复制</param> |
201 | /// <returns>成功复制的值个数</returns> |
202 | public static int CopyValueTo( this object source, object destination, IEnumerable< string > excludeName) |
203 | { |
204 | if (destination == null || source == null ) |
205 | { |
206 | return 0; |
207 | } |
208 | return ClassValueCopier.Copy(destination, source, source.GetType(), excludeName); |
209 | } |
210 |
211 | } |
212 | #endregion |
213 | } |
说明:
1,只能复制相同名称,相同类型的字段、属性
2,可以选择只复制某个父类、接口下的字段和属性
3,如果你的 .NET 版本不是 3.0及以上,得删掉扩展方法和 Linq 的引用