54

在 vs2008 中,是否可以编写适用于任何枚举的扩展方法。

我知道您可以针对特定枚举编写扩展方法,但我希望能够使用单个扩展方法来处理每个枚举。这可能吗?

4

7 回答 7

81

是的,只需针对基本Enum类型进行编码,例如

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

不利的一面是,您可能最终会做一些非常讨厌的事情,例如使用Enum.GetUnderlyingType、强制转换和根据枚举的基本类型进入不同的分支,但您可以找到一些好的用途它(例如,我们有适用于所有枚举的方法)IsOneOfIsCombinationOf

PS:请记住,在编写方法时,尽管不建议使用,但您可以使用floatanddouble作为枚举的基本类型,因此您需要一些特殊情况以及无符号值。

于 2008-11-09T22:34:01.970 回答
18

是的你可以。目标扩展类型是 type Enum。在 C# 中,这将作为:

public static void EnumExtension(this Enum e)
{
}

或者在 VB 中像这样:

<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub
于 2008-11-09T22:40:45.717 回答
18

仅供参考,这是我能够使用的枚举扩展方法的一个很好的例子。它为枚举实现了一个不区分大小写的 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;
        }
    }
}

您可以通过以下方式使用它:

public enum TestEnum
{
    A,
    B,
    C
}

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

以下是我访问的两个网站以帮助提出此代码:

枚举的不区分大小写的 TryParse

枚举的扩展方法

于 2009-06-18T00:01:57.120 回答
9

这是另一个示例-恕我直言,这比必须创建和初始化临时变量更好。

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); 
} 
于 2012-01-12T05:29:28.063 回答
4

您还可以实现以下转换方法:

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;
    }
}

这是一个示例用法:

int a = MyEnum.A.Convert<int>();
于 2012-06-25T14:22:18.113 回答
2

有时需要根据枚举的名称或值从一个枚举转换为另一个枚举。以下是如何使用扩展方法很好地完成它:

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)));
    }
}
于 2013-10-31T13:33:58.190 回答
1

制作 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>();
    }

使用示例:

public enum TestEnum { A,B,C };

TestEnum.A.toElementsCollection();
于 2015-07-20T22:39:20.863 回答