[C#] Enum에 확장 메서드를 추가하는 방법

이 Enum 코드가 있습니다.

enum Duration { Day, Week, Month };

이 Enum에 대한 확장 메서드를 추가 할 수 있습니까?



답변

사이트 에 따르면 :

확장 메서드는 팀의 다른 사람들이 실제로 발견하고 사용할 수있는 방식으로 기존 클래스에 대한 메서드를 작성하는 방법을 제공합니다. 열거 형이 다른 클래스와 같은 클래스라는 점을 감안할 때 다음과 같이 확장 할 수 있다는 것은 그리 놀라운 일이 아닙니다.

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 처리 중 일부를 중앙 집중화하고 더 나은 일을 할 수있을 때까지 추상화 할 수 있습니다. 값도 범위 내에 있는지 확인하십시오.

여기 Microsft MSDN에서 자세한 내용을 읽을 수 있습니다 .


답변

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과 다른 유형이기 때문에 작동합니다.


답변

물론 예를 들어 다음 DescriptionAttribue과 같이 enum값 에 대해 사용할 수 있습니다.

using System.ComponentModel.DataAnnotations;

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


답변

모든 답변은 훌륭하지만 특정 유형의 열거 형에 확장 메서드를 추가하는 것에 대해 이야기하고 있습니다.

명시 적 캐스팅 대신 현재 값의 int를 반환하는 것과 같은 모든 열거 형에 메서드를 추가하려면 어떻게해야합니까?

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 참조

그의 답변에 대해 ShawnFeatherly에게 감사드립니다.


답변

어떤 것이 든 확장 프로그램을 만들 수 있습니다 object( 모범 사례로 간주되지는 않지만 ). 확장 방법을 방법으로 이해하십시오 public static. 메소드에서 원하는 매개 변수 유형을 사용할 수 있습니다.

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


답변

MSDN을 참조하십시오 .

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


답변

방금 c # https://github.com/simonmau/enum_ext에 대한 열거 형 확장을 만들었습니다.

typesafeenum의 구현 일 뿐이지 만 잘 작동하므로 공유 할 패키지를 만들었습니다.

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

나는 예제가 쓸모가 없다는 것을 알고 있지만 아이디어를 얻습니다.)