如何向枚举添加扩展方法

我有这个 Enum 代码:

enum Duration { Day, Week, Month };

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

151296 次浏览

参见 MSDN

public static class Extensions
{
public static string SomeMethod(this Duration enumValue)
{
//Do something here
return enumValue.ToString("D");
}
}

根据 工地:

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

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

我认为枚举通常不是最好的选择,但至少这可以让您集中一些开关/if 处理并抽象它们,直到您可以做得更好。记得检查值也在范围内。

你可以在微软的 MSDN 上阅读更多的 给你

您可以为任何东西创建扩展,甚至是 object(尽管它是 不被认为是最佳做法)。理解扩展方法就像理解 public static方法一样。您可以在方法上使用任何喜欢的参数类型。

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

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

using System.ComponentModel;


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


[Description("Five days")]
Week,


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

现在你想要做的是:

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

您的扩展方法 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;
}

还可以向 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;
}
}
}

您可以执行以下操作来调用上面的扩展方法:

var result = Enum<Duration>.Count;

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

所有的答案都很棒,但是他们讨论的是向特定类型的枚举添加扩展方法。

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

public static class EnumExtensions
{
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;
}
}

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

多亏了 肖恩 · 费瑟利的回答

我们刚刚为 c # https://github.com/simonmau/enum_ext做了一个枚举扩展

它只是 typeesafeenum 的一个实现,但是它工作得很好,所以我们制作了一个包来分享——玩得开心

public sealed class Weekday : TypeSafeNameEnum<Weekday, int>
{
public static readonly Weekday Monday = new Weekday(1, "--Monday--");
public static readonly Weekday Tuesday = new Weekday(2, "--Tuesday--");
public static readonly Weekday Wednesday = new Weekday(3, "--Wednesday--");
....


private Weekday(int id, string name) : base(id, name)
{
}


public string AppendName(string input)
{
return $"{Name} {input}";
}
}

我知道这个例子有点没用,但你明白我的意思;)

一个简单的解决办法。

public static class EnumExtensions
{
public static int ToInt(this Enum payLoad) {


return ( int ) ( IConvertible ) payLoad;


}
}


int num = YourEnum.AItem.ToInt();
Console.WriteLine("num : ", num);