Skip to content

Commit e10e886

Browse files
committed
fix cloning of AssemblyName
1 parent 0864b8a commit e10e886

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

FastCloner.Tests/SpecialCaseTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,4 +3023,30 @@ public void Drawing_Brush_DeepClone_Test()
30233023
original.Color = Color.Blue;
30243024
Assert.That(clone.Color.B, Is.EqualTo(0));
30253025
}
3026+
3027+
[Test]
3028+
public void AssemblyName_DeepClone_Test()
3029+
{
3030+
// Arrange
3031+
var original = new AssemblyName
3032+
{
3033+
Name = "MyTestAssembly",
3034+
Version = new Version(1, 2, 3, 4)
3035+
};
3036+
var originalVersion = new Version(1, 2, 3, 4);
3037+
3038+
// Act
3039+
var clone = original.DeepClone();
3040+
original.Version = new Version(5, 6, 7, 8); // Modify the original
3041+
3042+
// Assert
3043+
Assert.Multiple(() =>
3044+
{
3045+
Assert.That(clone, Is.Not.Null);
3046+
Assert.That(clone, Is.Not.SameAs(original));
3047+
Assert.That(clone.Name, Is.EqualTo("MyTestAssembly"));
3048+
Assert.That(clone.Version, Is.EqualTo(originalVersion));
3049+
Assert.That(clone.Version, Is.Not.EqualTo(original.Version));
3050+
});
3051+
}
30263052
}

FastCloner/Code/FastClonerExprGenerator.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.ObjectModel;
77
using System.Dynamic;
88
using System.Linq.Expressions;
9+
using System.Net;
910
using System.Reflection;
1011

1112
namespace FastCloner.Code;
@@ -132,11 +133,11 @@ public ConstructorInfoEx(ConstructorInfo constructor)
132133
// take parameterless constructor
133134
ConstructorInfo? ctor = type.GetConstructor(Type.EmptyTypes);
134135
return ctor != null ? new ConstructorInfoEx(ctor) : null;
135-
136+
136137
// using any other constructor that can be called without arguments increases chances we trigger side effects
137138
// we fall back to memberwise cloning instead
138-
ctor = type.GetConstructors().FirstOrDefault(c => c.GetParameters().All(p => p.HasDefaultValue));
139-
return ctor != null ? new ConstructorInfoEx(ctor) : null;
139+
// ctor = type.GetConstructors().FirstOrDefault(c => c.GetParameters().All(p => p.HasDefaultValue));
140+
// return ctor != null ? new ConstructorInfoEx(ctor) : null;
140141
}
141142

142143
private static NewExpression CreateNewExpressionWithCtor(ConstructorInfoEx ctorInfoEx)
@@ -394,7 +395,7 @@ private static object GenerateMemberwiseCloner(Type type, ExpressionPosition pos
394395
"System.Data.Entity.DynamicProxies.",
395396
"NHibernate.Proxy."
396397
]);
397-
398+
398399
private static readonly Dictionary<string, Func<Type, object?>> specialNamespaces = new Dictionary<string, Func<Type, object?>>
399400
{
400401
// these can be trusted to have their Clone() implemented properly

FastCloner/Code/FastClonerSafeTypes.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,16 @@ private static class TypePrefixes
104104
}
105105

106106
private static readonly Assembly propertyInfoAssembly = typeof(PropertyInfo).Assembly;
107-
private static bool IsReflectionType(Type type) => type.FullName?.StartsWith(TypePrefixes.SystemReflection) is true && Equals(type.GetTypeInfo().Assembly, typeof(PropertyInfo).GetTypeInfo().Assembly);
107+
108+
private static bool IsReflectionType(Type type)
109+
{
110+
if (type == typeof(AssemblyName))
111+
{
112+
return false;
113+
}
114+
115+
return type.FullName?.StartsWith(TypePrefixes.SystemReflection) is true && Equals(type.GetTypeInfo().Assembly, typeof(PropertyInfo).GetTypeInfo().Assembly);
116+
}
108117

109118
private static IEnumerable<FieldInfo> GetAllTypeFields(Type type)
110119
{

0 commit comments

Comments
 (0)