Skip to content

Commit f191ea5

Browse files
committed
fix #282 map error on record type with empty ctor
1 parent b1137f5 commit f191ea5

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

src/Mapster.Tests/WhenMappingCollections.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
45
using System.Linq;
56
using Microsoft.VisualStudio.TestTools.UnitTesting;
67
using Shouldly;
@@ -262,5 +263,73 @@ IEnumerable<int> GetInts()
262263
GetInts().Adapt<int[,]>();
263264
i.ShouldBe(1);
264265
}
266+
267+
[TestMethod]
268+
public void TestEnumList()
269+
{
270+
var testClass = new CloneTestEnumContainerListContainer
271+
{
272+
List1 = new List<CloneTestEnumContainer>
273+
{
274+
new CloneTestEnumContainer
275+
{
276+
Type = CloneTestEnum.Value1,
277+
Value = 500
278+
}
279+
},
280+
List2 = new List<CloneTestEnumContainer>
281+
{
282+
new CloneTestEnumContainer
283+
{
284+
Type = CloneTestEnum.Value5,
285+
Value = 500
286+
}
287+
}
288+
};
289+
290+
var cloneTest = testClass.Adapt<CloneTestEnumContainerListContainer>();
291+
foreach (var paymentCompoent in testClass.CombinedLists)
292+
{
293+
cloneTest.CombinedLists.ShouldContain(x => x.Type == paymentCompoent.Type && x.Value == paymentCompoent.Value);
294+
}
295+
}
296+
297+
#region TestClass
298+
299+
[Flags]
300+
public enum CloneTestEnum
301+
{
302+
Value1 = 1,
303+
Value2 = 2,
304+
Value3 = 100,
305+
Value4 = 200,
306+
Value5 = 300
307+
}
308+
309+
public class CloneTestEnumContainer
310+
{
311+
public CloneTestEnumContainer()
312+
{
313+
314+
}
315+
316+
public CloneTestEnumContainer(CloneTestEnum type, decimal value)
317+
{
318+
Type = type;
319+
Value = value;
320+
}
321+
322+
public CloneTestEnum Type { get; set; }
323+
public decimal Value { get; set; }
324+
}
325+
326+
public class CloneTestEnumContainerListContainer
327+
{
328+
public List<CloneTestEnumContainer> List1 { get; set; } = new List<CloneTestEnumContainer>(); //parts of the pricing calcs that need VAT added
329+
public List<CloneTestEnumContainer> List2 { get; set; } = new List<CloneTestEnumContainer>(); //parts of the pricing calcs that must NOT have VAT
330+
public ReadOnlyCollection<CloneTestEnumContainer> CombinedLists => List1.Concat(List2).ToList().AsReadOnly();
331+
}
332+
333+
#endregion
265334
}
266335
}

src/Mapster/Utils/ReflectionUtils.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ public static IEnumerable<Type> GetAllInterfaces(this Type interfaceType)
8787
{
8888
var allInterfaces = new HashSet<Type>();
8989
var interfaceQueue = new Queue<Type>();
90+
9091
allInterfaces.Add(interfaceType);
92+
yield return interfaceType;
93+
9194
interfaceQueue.Enqueue(interfaceType);
9295
while (interfaceQueue.Count > 0)
9396
{
@@ -96,11 +99,12 @@ public static IEnumerable<Type> GetAllInterfaces(this Type interfaceType)
9699
{
97100
if (allInterfaces.Contains(subInterface))
98101
continue;
102+
99103
allInterfaces.Add(subInterface);
104+
yield return subInterface;
100105
interfaceQueue.Enqueue(subInterface);
101106
}
102107
}
103-
return allInterfaces;
104108
}
105109

106110
public static bool IsCollection(this Type type)
@@ -171,16 +175,21 @@ public static bool IsRecordType(this Type type)
171175
props.All(p => p.SetterModifier != AccessModifier.Public))
172176
return true;
173177

174-
//1 non-empty constructor
175-
var ctors = type.GetConstructors().Where(ctor => ctor.GetParameters().Length > 0).ToList();
178+
//1 constructor
179+
var ctors = type.GetConstructors().ToList();
176180
if (ctors.Count != 1)
177181
return false;
178182

183+
//ctor must not empty
184+
var ctorParams = ctors[0].GetParameters();
185+
if (ctorParams.Length == 0)
186+
return false;
187+
179188
//all parameters should match getter
180189
return props.All(prop =>
181190
{
182191
var name = prop.Name.ToPascalCase();
183-
return ctors[0].GetParameters().Any(p => p.ParameterType == prop.Type && p.Name?.ToPascalCase() == name);
192+
return ctorParams.Any(p => p.ParameterType == prop.Type && p.Name?.ToPascalCase() == name);
184193
});
185194
}
186195

0 commit comments

Comments
 (0)