Automapping fails when property is overridden with new on subclass

This might be a bit of an edge case, and it might be some bad modeling, but I wanted to check if it should work.

If we map an instance of a subclass with a property X marked as “new” (because it should have the same name as in the base calss) to another class, the values use the value from the base class and not from the subclass.

Here are 3 test cases:

namespace Tests
{
    using ServiceStack;
    using Xunit;

    public class Test
    {
        [Fact]
        public void ConvertingFromClassWithNewPropertiesUsesValuesForNewProperties()
        {
            var x = new BaseClassInherited
            {
                Id = "id",
                Content = new MultiLanguageThingieReduced
                {
                    Name = "name",
                    Value = "value"
                }
            };
            var d = x.ConvertTo<InterfaceDto>();
            Assert.NotNull(d.Content);
            Assert.Equal("id", d.Id);
            Assert.Equal("name", d.Content.Name);
            Assert.Equal("value", d.Content.Value);
        }

        [Fact]
        public void ConvertingFromClassWithNewPropertiesWithBasePropertyFilledUsesValuesForNewProperties()
        {
            var x = new BaseClassInherited
            {
                Id = "id",
                Content = new MultiLanguageThingieReduced
                {
                    Name = "subclass name",
                    Value = "subclass value"
                }
            };
            ((BaseClass)x).Content = new ComplexValueClass()
            {
                Name = "name"
            };
            var d = x.ConvertTo<InterfaceDto>();
            Assert.NotNull(d.Content);
            Assert.Equal("id", d.Id);
            Assert.Equal("subclass name", d.Content.Name);
            Assert.Equal("subclass value", d.Content.Value);
        }

        [Fact]
        public void BaseConversionWorks()
        {
            var x = new BaseClass
            {
                Id = "id",
                Content = new ComplexValueClass
                {
                    Name = "name"
                }
            };

            var d = x.ConvertTo<InterfaceDto>();
            Assert.NotNull(d.Content);
            Assert.Equal("id", d.Id);
            Assert.Equal("name", d.Content.Name);
        }
    }

    class BaseClass
    {
        public string Id { get; set; }
        public ComplexValueClass Content { get; set; }
    }

    class ComplexValueClass
    {
        public string Name { get; set; }
    }

    class BaseClassInherited : BaseClass
    {
        public new MultiLanguageThingieReduced Content { get; set; }
    }


    class MultiLanguageThingieReduced
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }

    class InterfaceDto
    {
        public string Id { get; set; }
        public MultiLanguageThingieReducedDto Content { get; set; }
    }


    class MultiLanguageThingieReducedDto
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }

}

I’d expect non-virtual properties like new not to be copied over if you’re converting from the base type since it wont show up in the reflection API’s of the base type.

Sure, but I’m converting from the inherited class, not base class, or am I not?

        var x = new BaseClassInherited
        {
            Id = "id",
            Content = new MultiLanguageThingieReduced
            {
                Name = "name",
                Value = "value"
            }
        };
        var d = x.ConvertTo<InterfaceDto>();

x here will be of type BaseClassInherited (sorry about the name), so ConvertTo should use the properties from that class (which includes the property marked as new) , should it not?

ok I’ve had a look the issue is having duplicated properties with the same name which messes the Reflection API’s, e.g. trying to resolve the property throws an AmbiguousMatchException:

typeof(BaseClassInherited).GetProperty("Content");

It would work by either uncommenting the Content property in the sub or super classes. It would require a refactor to support this which would change existing behavior which I don’t want to do since this is a corner-case and it would change existing behavior existing code bases could be relied on.

I was hoping this wouldn’t be a big issue, but we can work without this case.

Thanks for looking into it.