увеличить производительность func <T>для отражения - PullRequest
0 голосов
/ 11 июля 2019

В настоящее время я работаю над фрагментом кода, который определяет Type и Value поля (все enum), чтобы мы могли найти перевод для конкретного перечисления.Я знаю, что это довольно дорого, но я не вижу лучшего решения.Кто знает, что лучше подходит?

Я использую автомаппер для отображения ..

//removed some code
CreateMap<CarModel, CarDTO>
    .ForMember(dst => dst.CarBodyType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.CarBodyType)))
    .ForMember(dst => dst.FuelType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.FuelType)))
    .ForMember(dst => dst.GearType, opt => opt.MapFrom((detail, dto, _, context) => ResolveEnumTranslation(detail, context, car => car.GearType)))
//removed more for clearity (there are more enums)

private string ResolveEnumTranslation(CarDetail carDetail, ResolutionContext context, Func<CarDetail, object> property)
{
    var selectedEnum = property.Invoke(carDetail);

    if (context.Items.TryGetValue(localeKey, out var locale) && locale is string localeString)
    {
        return carDetail.Country.Translations
            .FirstOrDefault(t => t.EnumType == selectedEnum.GetType().Name
                        && t.EnumValue == (int)selectedEnum
                        && string.Equals(t.CountryLocale?.Locale, localeString, StringComparison.OrdinalIgnoreCase))
            ?.TranslatedValue ?? property.Invoke(carDetail).ToString();
    }

    return selectedEnum.ToString();
}

действительно любопытно, что было бы лучше.

1 Ответ

1 голос
/ 12 июля 2019

Вы можете сделать метод универсальным для типа enum, который позволяет передавать значение enum как есть.

Это позволяет получить тип enum через typeof(T), который происходит во время компиляции, тогда как selectedEnum.GetType() происходит во время выполнения.

Вам придется указать, улучшает ли это производительность.

Начиная с C# 7.3, вы даже можете использовать общее ограничение Enum для защиты того, что значение enum передается в качестве аргумента; например. where T : Enum

Вызовите метод ниже через

ResolveEnumTranslation(detail, context, car.GearType)

private string ResolveEnumTranslation<T>(
     CarDetail carDetail, ResolutionContext context, T selectedEnum
     ) where T : Enum
{
    var typeName = typeof(T).Name;

    if (context.Items.TryGetValue(localeKey, out var locale) && locale is string localeString)
    {
        return carDetail.Country.Translations
            .FirstOrDefault(t =>
                 t.EnumType == typeName
                 && t.EnumValue == Convert.ToInt32(selectedEnum)
                 && string.Equals(t.CountryLocale?.Locale, localeString, StringComparison.OrdinalIgnoreCase)
            )?.TranslatedValue ?? selectedEnum.ToString();
    }

    return selectedEnum.ToString();
}
...