Использование Enum как / с выражениями?

Можно ли использовать перечисление с выражениями для отражения значений перечисления? Рассмотрим эту гипотетическую процедуру:

public enum Fruit
{
  Apple,
  Pear
}

public void Foo(Fruit fruit)
{
  Foo<Fruit>(() => fruit);
}

public void Foo<T>(Expression<Func<T>> expression)
{
    //... example: work with Fruit.Pear and reflect on it
}

Bar() предоставит мне информацию о перечислении, но я хочу работать с фактическим значением.

Предыстория: я добавлял несколько вспомогательных методов для возврата информации CustomAttribute для типов и задавался вопросом, можно ли использовать аналогичную процедуру для перечислений.

Я полностью осознаю, что вы можете работать с типом enum, чтобы получить CustomAttributes таким образом.

Обновление:

Я использую аналогичную концепцию в MVC со вспомогательными расширениями:

public class HtmlHelper<TModel> : System.Web.Mvc.HtmlHelper<TModel>
{
    public void BeginLabelFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        string name = ExpressionHelper.GetExpressionText(expression);
    }
}

В этом примере name будет именем члена модели. Я хочу сделать то же самое с перечислениями, поэтому имя будет enum 'member'. Это вообще возможно?

Обновленный пример:

public enum Fruit
{
  [Description("I am a pear")]
  Pear
}

public void ARoutine(Fruit fruit)
{
  GetEnumDescription(() => fruit); // returns "I am a pear"
}

public string GetEnumDescription<T>(/* what would this be in a form of expression? Expression<T>? */)
{
  MemberInfo memberInfo;
  // a routine to get the MemberInfo(?) 'Pear' from Fruit - is this even possible?

  if (memberInfo != null)
  {
    return memberInfo.GetCustomAttribute<DescriptionAttribute>().Description;
  }

  return null; // not found or no description
}

person Phil Cooper    schedule 23.08.2013    source источник
comment
Вы хотели сделать так, чтобы Foo call Bar? Почему вы здесь используете деревья выражений? Чего вы на самом деле пытаетесь достичь? На данный момент ваш вопрос очень расплывчатый.   -  person Jon Skeet    schedule 23.08.2013
comment
@JonSkeet Извините, случай изменения перед публикацией. Я обновил его, а также добавил пример с подпрограммой, используемой для Mvc, где имя свойства извлекается для метки.   -  person Phil Cooper    schedule 23.08.2013
comment
До сих пор неясно, почему вы просто не вызываете ToString(), который даст вам имя, связанное со значением.   -  person Jon Skeet    schedule 23.08.2013
comment
Меня не интересует имя перечисления, мне было интересно, можно ли использовать тот же метод выражения для получения атрибута перечисления. В этом вопросе описывается использование отражения, как получить настраиваемый атрибут для значение перечисления. Учитывая, что этот подход затрагивает MemberInfo - нельзя ли использовать выражение с перечислением, чтобы получить MemberInfo значения и таким образом получить атрибуты?   -  person Phil Cooper    schedule 23.08.2013
comment
Что вы имеете в виду под атрибутом enum? Вы сказали, что name будет enum 'member' - если вы имеете в виду Pear или Apple, это именно то, что вы получаете от ToString. Если это не то, что вы хотите, вам действительно нужно привести полный пример того, как вы собираетесь вызвать Foo(Fruit) и чего вы ожидаете от результата.   -  person Jon Skeet    schedule 23.08.2013
comment
Это то, что вы ищите? weblogs.asp.net/grantbarrington/archive/2009/01/19/   -  person thumbmunkeys    schedule 23.08.2013


Ответы (1)


Для этого вам не нужны Expressions. Все, что вам нужно знать, это то, что enums имеют поле для каждого из своих значений. Это означает, что вы можете сделать что-то вроде:

public static string GetEnumDescription<T>(T enumValue) where T : struct, Enum
{
    FieldInfo field = typeof(T).GetField(enumValue.ToString());

    if (field != null)
    {
        var attribute = field.GetCustomAttribute<DescriptionAttribute>();

        if (attribute != null)
            return attribute.Description;
    }

    return null; // not found or no description
}
person svick    schedule 23.08.2013
comment
Из C # 7.3 вы можете использовать where T : Enum - person procma; 24.01.2020