如何向枚举添加扩展方法

时间:2022-09-23 08:09:01

I have this Enum code:

我有这个Enum代码:

enum Duration { Day, Week, Month };

Can I add a extension methods for this Enum?

我可以为这个枚举添加扩展方法吗?

6 个解决方案

#1


62  

According to this site:

根据这个网站:

Extension methods provide a way to write methods for existing classes in a way other people on your team might actually discover and use. Given that enums are classes like any other it shouldn’t be too surprising that you can extend them, like:

扩展方法提供了一种为现有类编写方法的方法,您的团队中的其他人实际上可能会发现并使用这种方法。考虑到枚举和其他类一样,您可以扩展它们也就不足为奇了,比如:

enum Duration { Day, Week, Month };

static class DurationExtensions {
  public static DateTime From(this Duration duration, DateTime dateTime) {
    switch duration {
      case Day:   return dateTime.AddDays(1);
      case Week:  return dateTime.AddDays(7);
      case Month: return dateTime.AddMonths(1);
      default:    throw new ArgumentOutOfRangeException("duration")
    }
  }
}

I think enums are not the best choice in general but at least this lets you centralize some of the switch/if handling and abstract them away a bit until you can do something better. Remember to check the values are in range too.

我认为枚举并不是最好的选择,但至少这可以让你集中一些开关/如果处理并抽象它们,直到你能做得更好。还记得检查取值范围。

You can read more here at Microsft MSDN.

你可以在Microsft MSDN上阅读更多。

#2


26  

You can also add an extension method to the Enum type rather than an instance of the Enum:

您还可以向Enum类型添加扩展方法,而不是Enum的实例:

/// <summary> Enum Extension Methods </summary>
/// <typeparam name="T"> type of Enum </typeparam>
public class Enum<T> where T : struct, IConvertible
{
    public static int Count
    {
        get
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("T must be an enumerated type");

            return Enum.GetNames(typeof(T)).Length;
        }
    }
}

You can invoke the extension method above by doing:

您可以通过以下操作调用上面的扩展方法:

var result = Enum<Duration>.Count;

It's not a true extension method. It only works because Enum<> is a different type than System.Enum.

它不是一个真正的扩展方法。它之所以有效,是因为Enum<>是与System.Enum不同的类型。

#3


20  

Of course you can, say for example, you want to use the DescriptionAttribue on your enum values:

当然,你可以,例如,你想在enum值上使用DescriptionAttribue:

using System.ComponentModel.DataAnnotations;

public enum Duration 
{ 
    [Description("Eight hours")]
    Day,

    [Description("Five days")]
    Week,

    [Description("Twenty-one days")] 
    Month 
}

Now you want to be able to do something like:

现在你想做的是:

Duration duration = Duration.Week;
var description = duration.GetDescription(); // will return "Five days"

Your extension method GetDescription() can be written as follows:

您的扩展方法GetDescription()可以写为:

using System.ComponentModel;
using System.Reflection;

public static string GetDescription(this Enum value)
{
    FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
    if (fieldInfo == null) return null;
    var attribute = (DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));
    return attribute.Description;
}

#4


13  

All answers are great, but they are talking about adding extension method to Specific type of enum

所有的答案都很好,但是他们正在讨论向特定类型的enum添加扩展方法

what if you want to add method to all enums like returning an int of current value instead of explicit casting

如果您想向所有枚举添加方法,比如返回当前值的int类型,而不是显式强制类型转换,该怎么办

public static class EnumExtentions
{
    public static int ToInt<T>(this T soure) where T : IConvertible//enum
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException("T must be an enumerated type");

        return (int) (IConvertible) soure;
    }

    //ShawnFeatherly funtion (above answer) but as extention method
    public static int Count<T>(this T soure) where T : IConvertible//enum
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException("T must be an enumerated type");

        return Enum.GetNames(typeof(T)).Length;
    }
}

the trick behind IConvertible is its Inheritance Hierarchy see MDSN

IConvertible背后的技巧是它的继承层次结构参见MDSN

thanks for ShawnFeatherly for his answer

谢谢肖菲利的回答

#5


6  

You can create an extension for anything, even object(although that's not considered best-practice). Understand an extension method just as a public static method. You can use whatever parameter-type you like on methods.

您可以为任何东西创建扩展,甚至对象(尽管这不是最佳实践)。理解扩展方法,就像理解公共静态方法一样。您可以在方法上使用任何您喜欢的参数类型。

public static class DurationExtensions
{
  public static int CalculateDistanceBetween(this Duration first, Duration last)
  {
    //Do something here
  }
}

#6


3  

See MSDN.

看到MSDN。

public static class Extensions
{
  public static void SomeMethod(this Duration enumValue)
  {
    //Do something here
  }
}

#1


62  

According to this site:

根据这个网站:

Extension methods provide a way to write methods for existing classes in a way other people on your team might actually discover and use. Given that enums are classes like any other it shouldn’t be too surprising that you can extend them, like:

扩展方法提供了一种为现有类编写方法的方法,您的团队中的其他人实际上可能会发现并使用这种方法。考虑到枚举和其他类一样,您可以扩展它们也就不足为奇了,比如:

enum Duration { Day, Week, Month };

static class DurationExtensions {
  public static DateTime From(this Duration duration, DateTime dateTime) {
    switch duration {
      case Day:   return dateTime.AddDays(1);
      case Week:  return dateTime.AddDays(7);
      case Month: return dateTime.AddMonths(1);
      default:    throw new ArgumentOutOfRangeException("duration")
    }
  }
}

I think enums are not the best choice in general but at least this lets you centralize some of the switch/if handling and abstract them away a bit until you can do something better. Remember to check the values are in range too.

我认为枚举并不是最好的选择,但至少这可以让你集中一些开关/如果处理并抽象它们,直到你能做得更好。还记得检查取值范围。

You can read more here at Microsft MSDN.

你可以在Microsft MSDN上阅读更多。

#2


26  

You can also add an extension method to the Enum type rather than an instance of the Enum:

您还可以向Enum类型添加扩展方法,而不是Enum的实例:

/// <summary> Enum Extension Methods </summary>
/// <typeparam name="T"> type of Enum </typeparam>
public class Enum<T> where T : struct, IConvertible
{
    public static int Count
    {
        get
        {
            if (!typeof(T).IsEnum)
                throw new ArgumentException("T must be an enumerated type");

            return Enum.GetNames(typeof(T)).Length;
        }
    }
}

You can invoke the extension method above by doing:

您可以通过以下操作调用上面的扩展方法:

var result = Enum<Duration>.Count;

It's not a true extension method. It only works because Enum<> is a different type than System.Enum.

它不是一个真正的扩展方法。它之所以有效,是因为Enum<>是与System.Enum不同的类型。

#3


20  

Of course you can, say for example, you want to use the DescriptionAttribue on your enum values:

当然,你可以,例如,你想在enum值上使用DescriptionAttribue:

using System.ComponentModel.DataAnnotations;

public enum Duration 
{ 
    [Description("Eight hours")]
    Day,

    [Description("Five days")]
    Week,

    [Description("Twenty-one days")] 
    Month 
}

Now you want to be able to do something like:

现在你想做的是:

Duration duration = Duration.Week;
var description = duration.GetDescription(); // will return "Five days"

Your extension method GetDescription() can be written as follows:

您的扩展方法GetDescription()可以写为:

using System.ComponentModel;
using System.Reflection;

public static string GetDescription(this Enum value)
{
    FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
    if (fieldInfo == null) return null;
    var attribute = (DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));
    return attribute.Description;
}

#4


13  

All answers are great, but they are talking about adding extension method to Specific type of enum

所有的答案都很好,但是他们正在讨论向特定类型的enum添加扩展方法

what if you want to add method to all enums like returning an int of current value instead of explicit casting

如果您想向所有枚举添加方法,比如返回当前值的int类型,而不是显式强制类型转换,该怎么办

public static class EnumExtentions
{
    public static int ToInt<T>(this T soure) where T : IConvertible//enum
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException("T must be an enumerated type");

        return (int) (IConvertible) soure;
    }

    //ShawnFeatherly funtion (above answer) but as extention method
    public static int Count<T>(this T soure) where T : IConvertible//enum
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException("T must be an enumerated type");

        return Enum.GetNames(typeof(T)).Length;
    }
}

the trick behind IConvertible is its Inheritance Hierarchy see MDSN

IConvertible背后的技巧是它的继承层次结构参见MDSN

thanks for ShawnFeatherly for his answer

谢谢肖菲利的回答

#5


6  

You can create an extension for anything, even object(although that's not considered best-practice). Understand an extension method just as a public static method. You can use whatever parameter-type you like on methods.

您可以为任何东西创建扩展,甚至对象(尽管这不是最佳实践)。理解扩展方法,就像理解公共静态方法一样。您可以在方法上使用任何您喜欢的参数类型。

public static class DurationExtensions
{
  public static int CalculateDistanceBetween(this Duration first, Duration last)
  {
    //Do something here
  }
}

#6


3  

See MSDN.

看到MSDN。

public static class Extensions
{
  public static void SomeMethod(this Duration enumValue)
  {
    //Do something here
  }
}