简体   繁体   中英

Generic Enum Converter for AutoMapper

I have the following string to enum converter:

    public static T ParseString<T>(string stringValue) where T : struct
    {
        if (!string.IsNullOrWhiteSpace(stringValue))
        {
            stringValue = stringValue.Replace(" ", "_");
            T result;

            if (Enum.TryParse<T>(stringValue, out result))
            {
                return result;
            }
        }

        return default(T);
    }

Which I am using in a couple of automapper converters:

public sealed class StringToGuaranteeTypeConverter : ITypeConverter<string, GuaranteeType>
{
    public GuaranteeType Convert(string source, GuaranteeType destination, ResolutionContext context)
    {
        return EnumExtensions.ParseString<GuaranteeType>(source);
    }
}

public sealed class StringToWhyChooseTypeConverter : ITypeConverter<string, WhyChooseType>
{
    public WhyChooseType Convert(string source, WhyChooseType destination, ResolutionContext context)
    {
        return EnumExtensions.ParseString<WhyChooseType>(source);
    }
}

Is there a way to create a generic enum converter for automapper rather than having to create the same thing for each enum I need to convert?

I was hoping for something along the lines of:

public sealed class StringToEnumConverter : ITypeConverter<string, T> // this line fails as it does not know what T is here
{
    public T Convert<T>(string source, T destination, ResolutionContext context)
    {
        return EnumExtensions.ParseString<T>(source);
    }
}

But my knowledge of how to use T is quite limited so obviously this does not work. Is it even possible with an inherited class?

You have two problems:

1) You need to include the generic type parameter on the StringToEnumConverter class so that it can be passed to the interface definition

2) You need to constrain the generic type since your parser method is constrained

public sealed class StringToEnumConverter<T> : ITypeConverter<string, T>
    where T : struct
{
    public T Convert(string source, T destination, ResolutionContext context)
    {
        return EnumExtensions.ParseString<T>(source);
    }
}

If you do that, it should work fine:

Mapper.Initialize(cfg =>
                  {
                      cfg.CreateMap<string, GuaranteeType>().ConvertUsing(new StringToEnumConverter<GuaranteeType>());
                      cfg.CreateMap<string, WhyChooseType>().ConvertUsing(new StringToEnumConverter<WhyChooseType>());
                  });

WhyChooseType instance = Mapper.Map<WhyChooseType>("2");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM