diff --git a/src/Mapster.Tests/WhenMappingInitProperty.cs b/src/Mapster.Tests/WhenMappingInitProperty.cs index 4fda129..6c1352d 100644 --- a/src/Mapster.Tests/WhenMappingInitProperty.cs +++ b/src/Mapster.Tests/WhenMappingInitProperty.cs @@ -19,7 +19,7 @@ public void WhenMappingToHiddenandNewInitFieldDestination() var c = source.Adapt(); var s = source.Adapt(new BDestination()); - ((ADestination)c).Id.ShouldBe(156); + ((ADestination)c).Id.ShouldBe(default); // Hidden Base member is not mapping s.Id.ShouldBe(156); } @@ -33,7 +33,7 @@ public void WhenMappingToHiddenandNewInitFieldWithConstructUsing() var c = source.Adapt(); var s = source.Adapt(new BDestination()); - ((ADestination)c).Id.ShouldBe(256); + ((ADestination)c).Id.ShouldBe(default); // Hidden Base member is not mapping s.Id.ShouldBe(256); } diff --git a/src/Mapster/Utils/ReflectionUtils.cs b/src/Mapster/Utils/ReflectionUtils.cs index dae413d..e063c55 100644 --- a/src/Mapster/Utils/ReflectionUtils.cs +++ b/src/Mapster/Utils/ReflectionUtils.cs @@ -69,23 +69,44 @@ public static IEnumerable GetFieldsAndProperties(this Type type, var bindingFlags = BindingFlags.Instance | BindingFlags.Public; if (includeNonPublic) bindingFlags |= BindingFlags.NonPublic; - + + var currentTypeMembers = type.FindMembers(MemberTypes.Property | MemberTypes.Field, + BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + (x, y) => true, type.FullName); + if (type.GetTypeInfo().IsInterface) { var allInterfaces = GetAllInterfaces(type); - return allInterfaces.SelectMany(GetPropertiesFunc); + return allInterfaces.SelectMany(x => GetPropertiesFunc(x, currentTypeMembers)); } - return GetPropertiesFunc(type).Concat(GetFieldsFunc(type)); + return GetPropertiesFunc(type, currentTypeMembers).Concat(GetFieldsFunc(type, currentTypeMembers)); - IEnumerable GetPropertiesFunc(Type t) => t.GetProperties(bindingFlags) - .Where(x => x.GetIndexParameters().Length == 0) + IEnumerable GetPropertiesFunc(Type t, MemberInfo[] currentTypeMembers) => t.GetProperties(bindingFlags) + .Where(x => x.GetIndexParameters().Length == 0).DropHiddenMembers(currentTypeMembers) .Select(CreateModel); - IEnumerable GetFieldsFunc(Type t) => t.GetFields(bindingFlags) + IEnumerable GetFieldsFunc(Type t, MemberInfo[] overlapMembers) => + t.GetFields(bindingFlags).DropHiddenMembers(overlapMembers) .Select(CreateModel); } + public static IEnumerable DropHiddenMembers(this IEnumerable allMembers, ICollection currentTypeMembers) where T : MemberInfo + { + var compareMemberNames = allMembers.IntersectBy(currentTypeMembers.Select(x => x.Name), x => x.Name).Select(x => x.Name); + + foreach (var member in allMembers) + { + if (compareMemberNames.Contains(member.Name)) + { + if (currentTypeMembers.First(x => x.Name == member.Name).MetadataToken == member.MetadataToken) + yield return member; + } + else + yield return member; + } + } + // GetProperties(), GetFields(), GetMethods() do not return properties/methods from parent interfaces, // so we need to process every one of them separately. public static IEnumerable GetAllInterfaces(this Type interfaceType)