Pergunta

Em vs2008, é possível escrever um métodos de extensão que seriam aplicáveis ??a qualquer enumeração.

Eu sei que você pode escrever métodos de extensão contra uma enumeração específica, mas eu quero ser capaz de cada enumeração usando um único método de extensão. Isso é possível?

Foi útil?

Solução

Sim, basta código contra o tipo base Enum, por exemplo.

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

O lado negativo é que você provavelmente vai acabar fazendo algumas coisas bastante desagradável como encontrar o tipo base real, usando Enum.GetUnderlyingType , fundição, e descendo ramos diferentes, dependendo do que o tipo base da enumeração é, mas você pode encontrar alguns bons usos para ele (por exemplo, temos IsOneOf e métodos IsCombinationOf que se aplicam a todos os enums).

PS:. Lembre-se ao escrever o método que, embora mal aconselhado, você pode usar float e double como os tipos de base para enums assim que você vai precisar de alguns casos especiais para aqueles, bem como os valores não assinados

Outras dicas

Sim, você pode. O tipo de destino extenstion é do tipo Enum. Em C #, isso seria feito como:

public static void EnumExtension(this Enum e)
{
}

ou como esta em VB:

<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub

FYI Aqui é um grande exemplo de um método de enumeração de extensão que eu tenho sido capaz de usar. Ele implementa um caso insensível função para enums TryParse ():

public static class ExtensionMethods
{
    public static bool TryParse<T>(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;
        }
    }
}

Você iria utilizá-lo da seguinte maneira:

public enum TestEnum
{
    A,
    B,
    C
}

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

Aqui estão os dois sites que visitei a ajuda venha com este código:

Insensitive Case TryParse para enums

métodos de extensão para Enums

Aqui está outro exemplo -. IMHO também mais agradável do que ter que criar e inicializar uma variável temporário

public static class ExtensionMethods 
{
    public static void ForEach(this Enum enumType, Action<Enum> 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); 
} 

Você também pode implementar método de conversão da seguinte forma:

public static class Extensions
{
    public static ConvertType Convert<ConvertType>(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;
    }
}

Aqui está um exemplo de uso:

int a = MyEnum.A.Convert<int>();

Às vezes, há uma necessidade de converter de um enum para outro, com base no nome ou o valor do enum. Aqui está como isso pode ser feito muito bem com os métodos de extensão:

enum Enum1 { One = 1, Two = 2, Three = 3 };
enum Enum2 { Due = 2, Uno = 1 };
enum Enum3 { Two, One };

Enum2 e2 = Enum1.One.ConvertByValue<Enum2>();
Enum3 e3 = Enum1.One.ConvertByName<Enum3>();
Enum3 x2 = Enum1.Three.ConvertByValue<Enum3>();

public static class EnumConversionExtensions
{
    public static T ConvertByName<T>(this Enum value)
    {
        return (T)Enum.Parse(typeof(T), Enum.GetName(value.GetType(), value));
    }

    public static T ConvertByValue<T>(this Enum value)
    {
        return (T)((dynamic)((int)((object)value)));
    }
}

Outro exemplo de fazer extensão Enum -. Mas desta vez ele retorna o tipo de entrada enum

public static IEnumerable<T> toElementsCollection<T>(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<T>();
    }

Exemplo de utilização:

public enum TestEnum { A,B,C };

TestEnum.A.toElementsCollection();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top