2

I am trying to map an enum value to another using

CreateMap<Enum1, Enum2>()
                .ConvertUsingEnumMapping(m => m.MapByName())
                .ReverseMap();

The enums are like this

 public enum Enum1
    {
        action1 = 1,
        action2 = 2
        aliasAction1 = 1
    }

 public enum Enum2
    {
        action1 = 1,
        action2 = 2
        aliasAction1 = 1
    }

When running the mapping validation test using

configuration.AssertConfigurationIsValid();

I get an error regarding the enum value key already exists. Even though I am doing mapping by name instead of by value. Specifically

System.ArgumentException : An item with the same key has already been added. 

Is there any way to perform this mapping without doing it manually myself?

EDIT Extra info to avoid a possible hail-storm

I understand that non-unique enum values are to be frowned upon and avoided at all costs, but, the enum is provided from a third party that I need to convert to proto for internal use, thus the need for mapping using Automapper.

John Demetriou
  • 4,093
  • 6
  • 52
  • 88

1 Answers1

3

No, it's not possible and it's not AutoMapper's fault.

If you try to map it manually without AutoMapper it would more or less look like these few lines below. A switch, leading from one enum to another.

public Enum2 Convert(Enum1 source)
{
    switch (source)
    {
        case Enum1.action1:
            return Enum2.action1;
        case Enum1.action2:
            return Enum2.action2;
        case Enum1.aliasAction1:
            return Enum2.aliasAction1;
        default:
            throw new NotSupportedException();
    }
}

But wait... the compiler seems to have a problem with the case for aliasAction1:

case Enum1.aliasAction1:
    return Enum2.aliasAction1;

CS0152: The switch statement contains multiple cases with the label value '1'

It's because the switch statement already defines a path for value 1, which is action1. Even if the compiler allowed you to write such switch, the case for aliasAction1 would be unreachable, because the case for value 1 is already defined earlier, thus all enum members with value 1 would fall right in the first case.

Let's declare a variable for Enum1 and set its value to aliasAction1:

var enumValue = Enum1.aliasAction1;
Console.WriteLine(enumValue);

and the output will be:

action1

Compiler selects first value arbitrarily. Here is a great answer on non-unique enum values.

And when it comes to solution to your problem, I'd suggest creating a struct that will act as non-unique enum.

However, if you are aware and okay with non-unique enum members and simply want the mapping to work, then all you have to do is remove the CreateMap() because enum mapping work with AutoMapper by convention without any explicit configuration (as long as the names/values match).

Prolog
  • 2,698
  • 1
  • 18
  • 31
  • The enum is provided by a third-party that I need to convert to a proto class for internal use, so avoiding non-unique enums is out of the question. But I appreciate your help – John Demetriou Nov 09 '20 at 06:55