我有这个枚举代码:
enum Duration { Day, Week, Month };
我能为这个枚举类型添加扩展方法吗?
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");
}
}
}
我认为枚举通常不是最好的选择,但至少可以让你集中一些switch/if处理并将它们抽象化,直到你可以做得更好。记得也要检查数值范围。
您可以在微软MSDN网站这里了解更多信息。
Duration d = 0;
- GrahamEnum
(注意不是小写的enum
),就会跳转到元数据,其中包含了public abstract class Enum : ValueType, IComparable, ...
- 因此,在我看来它看起来像一个类,因为我认为enum
和Enum
是同义词。 - StayOnTarget/// <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;
static
以确保其所有方法都像扩展一样工作吗? - Jatin SanghviEnum<T>
的名称歧义有点令人困惑。这个类也可以被称为 EnumUtils<T>
,方法调用将解析为 EnumUtils<Duration>.Count
。 - Namoshekwhere T : System.Enum
替代where T : struct, IConvertible
(然后也可以删除ArgumentException)。 - Tobias XyDescriptionAttribute
: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;
}
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;
}
}
< p > IConvertible
的诀窍在于其继承层次结构,请参见MDSN
MyExtention.DoThing(myvalue)
),它可以工作,但实际上并没有附加到枚举上(例如 myvalue.DoThing()
)。 - Sinaesthetic一个简单的解决方法。
public static class EnumExtensions
{
public static int ToInt(this Enum payLoad) {
return ( int ) ( IConvertible ) payLoad;
}
}
int num = YourEnum.AItem.ToInt();
Console.WriteLine("num : ", num);
object
(尽管这不是最佳实践)。将扩展方法理解为public static
方法。你可以在方法上使用任何参数类型。public static class DurationExtensions
{
public static int CalculateDistanceBetween(this Duration first, Duration last)
{
//Do something here
}
}
public static class Extensions
{
public static string SomeMethod(this Duration enumValue)
{
//Do something here
return enumValue.ToString("D");
}
}
void
返回值有点奇怪。我会考虑一个更现实的示例。 - psubsee2003public 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}";
}
}
我知道这个例子有点无用,但你能理解我的意思;)
Day.IsWorkday()
而不是(Day & Days.Workday) > 0
,其中Days.Workday
被定义为Monday | Tuesday ... | Friday
。在我看来,前者更清晰,并且完全实现了后者。 - Sebastian Werk