Skip to content

Commit daa1eff

Browse files
committed
- Object.Clone() added
- ICloneable<T> is now deprecated
1 parent 6bcafa7 commit daa1eff

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

Core.Common.Standard/Extension/ObjectExtension.cs

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static void SetDefaults(this object target, object defaults, params strin
5656
}
5757
}
5858
}
59-
59+
6060
[DebuggerHidden]
6161
public static void SetFrom(this object target, object source, params string[] ignoreProperties)
6262
{
@@ -67,7 +67,7 @@ public static void SetFrom(this object target, object source, params string[] ig
6767
Type targetType = target.GetType();
6868
Type sourceType = source.GetType();
6969
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));
7171
foreach (PropertyInfo sourceProperty in sourceProperties)
7272
{
7373
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
102102
}
103103
}
104104
}
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+
}
105158
}
106-
}
159+
}

Core.Common.Standard/ICloneable.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
namespace KY.Core
1+
using System;
2+
3+
namespace KY.Core
24
{
5+
[Obsolete("Use ICloneable instead")]
36
public interface ICloneable<out T>
47
{
58
T Clone();
69
}
7-
}
10+
}

Core.Common.Standard/KY.Core.Common.Standard.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<RootNamespace>KY.Core</RootNamespace>
66
<AssemblyName>KY.Core.Common</AssemblyName>
7-
<Version>4.22.0</Version>
7+
<Version>4.23.0</Version>
88
<Authors>KY-Programming</Authors>
99
<Company>KY-Programmingp</Company>
1010
<Product>KY.Core</Product>
@@ -19,6 +19,7 @@ Contains Dependency Injection, Module Loader and some helper classes</Descriptio
1919
<PublishRepositoryUrl>true</PublishRepositoryUrl>
2020
<IncludeSymbols>true</IncludeSymbols>
2121
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
22+
<LangVersion>latest</LangVersion>
2223
</PropertyGroup>
2324

2425
<ItemGroup>

0 commit comments

Comments
 (0)