@@ -56,7 +56,7 @@ public static void SetDefaults(this object target, object defaults, params strin
56
56
}
57
57
}
58
58
}
59
-
59
+
60
60
[ DebuggerHidden ]
61
61
public static void SetFrom ( this object target , object source , params string [ ] ignoreProperties )
62
62
{
@@ -67,7 +67,7 @@ public static void SetFrom(this object target, object source, params string[] ig
67
67
Type targetType = target . GetType ( ) ;
68
68
Type sourceType = source . GetType ( ) ;
69
69
IEnumerable < PropertyInfo > sourceProperties = sourceType . GetProperties ( BindingFlags . GetProperty | BindingFlags . Instance | BindingFlags . Public )
70
- . Where ( x => x . CanRead && ! ignoreProperties . Contains ( x . Name ) ) ;
70
+ . Where ( x => x . CanRead && ! ignoreProperties . Contains ( x . Name ) ) ;
71
71
foreach ( PropertyInfo sourceProperty in sourceProperties )
72
72
{
73
73
PropertyInfo targetProperty = targetType . GetProperty ( sourceProperty . Name , /*BindingFlags.GetProperty | BindingFlags.SetProperty |*/ BindingFlags . Instance | BindingFlags . Public ) ;
@@ -102,5 +102,58 @@ public static void SetFrom(this object target, object source, params string[] ig
102
102
}
103
103
}
104
104
}
105
+
106
+ public static T Clone < T > ( this T source , params string [ ] ignoreProperties )
107
+ {
108
+ return Clone ( source , true , ignoreProperties ) ;
109
+ }
110
+
111
+ public static T Clone < T > ( this T source , bool useICloneable , params string [ ] ignoreProperties )
112
+ {
113
+ if ( useICloneable && source is ICloneable cloneable )
114
+ {
115
+ return ( T ) cloneable . Clone ( ) ;
116
+ }
117
+ if ( source == null )
118
+ {
119
+ return default ;
120
+ }
121
+ T target = ( T ) Activator . CreateInstance ( source . GetType ( ) ) ;
122
+ CloneAndSet ( source , target , ignoreProperties ) ;
123
+ return target ;
124
+ }
125
+
126
+ private static void CloneAndSet ( object source , object target , params string [ ] ignoreProperties )
127
+ {
128
+ IEnumerable < PropertyInfo > properties = source . GetType ( ) . GetProperties ( BindingFlags . GetProperty | BindingFlags . Instance | BindingFlags . Public )
129
+ . Where ( x => x . CanRead && ! ignoreProperties . Contains ( x . Name ) ) ;
130
+ foreach ( PropertyInfo property in properties )
131
+ {
132
+ object sourceValue = property . GetGetMethod ( ) . Invoke ( source , null ) ;
133
+ object targetValue = property . GetGetMethod ( ) . Invoke ( target , null ) ;
134
+ if ( targetValue != null && sourceValue != null && ! targetValue . GetType ( ) . IsPrimitive && targetValue is not string )
135
+ {
136
+ if ( targetValue is IList list )
137
+ {
138
+ list . Clear ( ) ;
139
+ if ( sourceValue is IEnumerable enumerable )
140
+ {
141
+ foreach ( object entry in enumerable )
142
+ {
143
+ list . Add ( entry ? . Clone ( ) ) ;
144
+ }
145
+ }
146
+ }
147
+ else
148
+ {
149
+ CloneAndSet ( sourceValue , targetValue , ignoreProperties ) ;
150
+ }
151
+ }
152
+ else if ( property . CanWrite )
153
+ {
154
+ property . GetSetMethod ( ) . Invoke ( target , new [ ] { sourceValue ? . Clone ( ) } ) ;
155
+ }
156
+ }
157
+ }
105
158
}
106
- }
159
+ }
0 commit comments