Search code examples
c#inheritanceautomapperparent-childmember-hiding

AutoMapper - Map child property hiding base class property


I'm encountering a quite stupid issue while trying to map a class to a derived class using AutoMapper with C#.

These are my classes:

class BaseParent {
    public string Name { get; set; }
    public BaseChild Child { get; set; }
}

class BaseChild {
    public int Age { get; set; }
}

class DerivedParent : BaseParent {
    public new DerivedChild Child { get; set; }
}

class DerivedChild : BaseChild { }

In particular, what I'm trying to achieve is that all the properties of the mapped class are correctly set. The issue is that the Child property of the mapped class is not set and remains null.

This is the mapping configuration I'm using:

var config = new MapperConfiguration(cfg => {
        cfg.CreateMap<BaseChild, DerivedChild>();
        cfg.CreateMap<BaseParent, DerivedParent>()
            .ForMember(dest => dest.Child, opt => opt.MapFrom(src => src.Child));
    });

Any help is appreciated.

Thanks

EDIT

Actually is not correct to say that Child property remains null. Debugging the code I can see that there are 2 child properties with the same name because of the new modifier used to hide the parent one.

Anyway, the property I need is still null.


Solution

  • Are you sure you're looking at it correctly?

    Given the following config:

    // Arrange
    var mapper = new Mapper(new MapperConfiguration(cfg => {
        cfg.CreateMap<BaseChild, DerivedChild>();
        cfg.CreateMap<BaseParent, DerivedParent>()
            .ForMember(dest => dest.Child, opt => opt.MapFrom(src => src.Child));
    }));
    var baseParent = new BaseParent { Name = "A", Child = new BaseChild { Age = 1 } };
    
    // Act
    var derived = mapper.Map<DerivedParent>(baseParent);
    

    I can assure you that:

    • derived.Child is certainly not null
    • It is of type DerivedChild
    • The hidden BaseChild is null

    Which you can see in the following (see working Fiddle):

    // Assert
    Assert.IsNotNull(derived);
    Assert.IsInstanceOf<DerivedParent>(derived);
    
    // The 'new' Child property is not null
    Assert.IsNotNull(derived.Child);
    Assert.IsInstanceOf<DerivedChild>(derived.Child);
    
    // The hidden property should be null
    Assert.IsNull(((BaseParent)derived).Child);