- 
                Notifications
    
You must be signed in to change notification settings  - Fork 2.4k
 
Closed
Description
Source/destination types
//source type
public class Well
{
    //balabala...
    public SpecialTags SpecialTags { get; set; }
    //balabala...
}
[Flags]
public enum SpecialTags
{
    None = 0,
    SendState = 1,
    NotSendZeroWhenOpen = 2,
}
//destination type
public class PostPutWellViewModel
{
    //balabala...
    public SpecialTags[] SpecialTags { get; set; } = Array.Empty<SpecialTags>();
    //balabala...
}Mapping configuration
public class MyAutoMapperProfile : Profile
{
    public MyAutoMapperProfile()
    {
        CreateMap<Well, PostPutWellViewModel>()
        .ReverseMap();
    }
}
class ArrayToEnum : IValueConverter<object, object>
{
    public object Convert(object sourceMember, ResolutionContext context)
    {
        return Enum.ToObject(sourceMember.GetType().GetElementType()!, ((int[])sourceMember).Aggregate(0, (p, n) => p | n));
    }
}
class EnumToArray : IValueConverter<object, object>
{
    public object Convert(object sourceMember, ResolutionContext context)
    {
        var list = Enum.GetValues(sourceMember.GetType()).Cast<Enum>().ToList();
        for (int i = list.Count - 1; i > -1; i--)
        {
            var e = (int)(object)list[i];
            if (e == 0 || (e & (int)sourceMember) != e)
                list.RemoveAt(i);
        }
        var r = Array.CreateInstance(sourceMember.GetType(), list.Count);
        for (int i = 0; i < list.Count; i++)
            r.SetValue(list[i], i);
        return r;
    }
}
//oops, throw null reference exception
var config = new AutoMapper.MapperConfiguration(cfg =>
{
    cfg.AddProfile<MyAutoMapperProfile>();
    cfg.Internal().ForAllPropertyMaps(pm => pm.SourceType != null && pm.SourceType.IsArray && pm.SourceType.GetElementType()!.IsEnum && pm.DestinationType.IsEnum || pm.SourceType != null && pm.SourceType.IsEnum && pm.DestinationType.IsArray && pm.DestinationType.GetElementType()!.IsEnum,
        (tm, mapper) =>
    {
        if (tm.SourceType.IsArray && tm.SourceType.GetElementType()!.IsEnum && tm.DestinationType.IsEnum)
        {
            mapper.ConvertUsing(new ArrayToEnum());
        }
        else if (tm.SourceType.IsEnum && tm.DestinationType.IsArray && tm.DestinationType.GetElementType()!.IsEnum)
        {
            mapper.ConvertUsing(new EnumToArray());
        }
    });
});Version: 12.0.1
Expected behavior and Actual behavior
I recently upgraded AutoMapper from version 8.1.1 to version 12.0.1, and then the code that used to work properly has a null reference exception. I don't know if this is a design change or some kind of bug, please help me, thanks!
According to my test, this problem started from version 11. I made a demo of version 8.1.1 and 12.0.1 to demonstrate the problem, and the code is almost identical in both versions.
Steps to reproduce
var mapper = config.CreateMapper();
var well = new Well();
well.SpecialTags = SpecialTags.SendState;
var vm = mapper.Map<PostPutWellViewModel>(well);