Методы расширения перечисления

В vs2008 можно ли написать методы расширения, которые будут применяться к любому перечислению.

Я знаю, что вы можете написать методы расширения для конкретного перечисления, но я хочу иметь возможность для каждого перечисления, используя один метод расширения. Это возможно?

вопрос задан 9.11.2008
Eric Haskins
5557 репутация

7 ответов


  • 81 рейтинг

    Да, просто код против базового типа Enum, e. г.

    public static void Something(this Enum e)
    {
        // code here
    }
    

    Недостатком является то, что вы, вероятно, в конечном итоге будете делать довольно неприятные вещи, такие как поиск реального базового типа, используя Enum.GetUnderlyingType , приведение и переход к различным ветвям в зависимости от того, какой базовый тип перечисления есть, но вы можете найти некоторые хорошие использования для этого (например, г. у нас есть методы IsOneOf и IsCombinationOf, которые применяются ко всем перечислениям).

    PS: Помните, когда пишете метод, который, хотя и не рекомендуется, вы можете использовать float и double в качестве базовых типов для перечислений, поэтому вам потребуются некоторые особые случаи для этих, а также для значений без знака.

    ответ дан Greg Beech, с репутацией 97692, 9.11.2008
  • 18 рейтинг

    Да, вы можете. Тип целевого расширения имеет тип Enum. В C # это будет сделано как:

    public static void EnumExtension(this Enum e)
    {
    }
    

    или как это в VB:

     _
    Public Sub EnumExtension(ByVal s As Enum)
    End Sub
    
    ответ дан Scott Dorman, с репутацией 34290, 9.11.2008
  • 18 рейтинг

    FYI Вот отличный пример метода Enum Extension, который я смог использовать. Реализует регистрозависимую функцию TryParse () для перечислений:

    public static class ExtensionMethods
    {
        public static bool TryParse(this Enum theEnum, string strType, 
            out T result)
        {
            string strTypeFixed = strType.Replace(' ', '_');
            if (Enum.IsDefined(typeof(T), strTypeFixed))
            {
                result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
                return true;
            }
            else
            {
                foreach (string value in Enum.GetNames(typeof(T)))
                {
                    if (value.Equals(strTypeFixed, 
                        StringComparison.OrdinalIgnoreCase))
                    {
                        result = (T)Enum.Parse(typeof(T), value);
                        return true;
                    }
                }
                result = default(T);
                return false;
            }
        }
    }
    

    Вы будете использовать его следующим образом:

    public enum TestEnum
    {
        A,
        B,
        C
    }
    
    public void TestMethod(string StringOfEnum)
    {
        TestEnum myEnum;
        myEnum.TryParse(StringOfEnum, out myEnum);
    }
    

    Вот два сайта, которые я посетил, чтобы помочь придумать этот код:

    Без учета регистра TryParse для перечислений

    Методы расширения для перечислений

    ответ дан Michael La Voie, с репутацией 20492, 18.06.2009
  • 9 рейтинг

    Вот еще один пример - ИМХО также приятнее, чем необходимость создания и инициализации временной переменной.

    public static class ExtensionMethods 
    {
        public static void ForEach(this Enum enumType, Action action)
        {
            foreach (var type in Enum.GetValues(enumType.GetType()))
            {
                action((Enum)type);
            }
        }
    }
    
    public enum TestEnum { A,B,C } 
    public void TestMethod() 
    {
        default(TestEnum).ForEach(Console.WriteLine); 
    } 
    
    ответ дан Adriaan de Beer, с репутацией 422, 12.01.2012
  • 4 рейтинг

    Вы также можете реализовать метод преобразования следующим образом:

    public static class Extensions
    {
        public static ConvertType Convert(this Enum e)
        {
            object o = null;
            Type type = typeof(ConvertType);
    
            if (type == typeof(int))
            {
                o = Convert.ToInt32(e);
            }
            else if (type == typeof(long))
            {
                o = Convert.ToInt64(e);
            }
            else if (type == typeof(short))
            {
                o = Convert.ToInt16(e);
            }
            else
            {
                o = Convert.ToString(e);
            }
    
            return (ConvertType)o;
        }
    }
    

    Вот пример использования:

    int a = MyEnum.A.Convert();
    
    ответ дан Koray Bayram, с репутацией 61, 25.06.2012
  • 2 рейтинг

    Иногда необходимо выполнить преобразование из одного перечисления в другое, основываясь на имени или значении перечисления. Вот как это можно сделать с помощью методов расширения:

    enum Enum1 { One = 1, Two = 2, Three = 3 };
    enum Enum2 { Due = 2, Uno = 1 };
    enum Enum3 { Two, One };
    
    Enum2 e2 = Enum1.One.ConvertByValue();
    Enum3 e3 = Enum1.One.ConvertByName();
    Enum3 x2 = Enum1.Three.ConvertByValue();
    
    public static class EnumConversionExtensions
    {
        public static T ConvertByName(this Enum value)
        {
            return (T)Enum.Parse(typeof(T), Enum.GetName(value.GetType(), value));
        }
    
        public static T ConvertByValue(this Enum value)
        {
            return (T)((dynamic)((int)((object)value)));
        }
    }
    
    ответ дан Esge, с репутацией 151, 31.10.2013
  • 1 рейтинг

    Еще один пример создания расширения Enum - но на этот раз он возвращает тип входного enum.

    public static IEnumerable toElementsCollection(this T value) where T : struct, IConvertible
        {
            if (typeof(T).IsEnum == false) throw new Exception("typeof(T).IsEnum == false");
    
            return Enum.GetValues(typeof(T)).Cast();
        }
    

    Пример использования:

    public enum TestEnum { A,B,C };
    
    TestEnum.A.toElementsCollection();
    
    ответ дан Bronek, с репутацией 5942, 20.07.2015