내가 원하는 것은 다음과 같습니다. 플래그가 지정된 값이 결합 된 열거 형이 있습니다.
public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}
그래서 다음과 같이 할 수 있습니다.
MyEnum tester = MyEnum.FlagA | MyEnum.FlagB
if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a
불행히도 제약 조건에 열거 형 제한이없고 클래스와 구조체 만있는 C #의 제네릭입니다. C #은 열거 형을 구조체로 보지 않으므로 (값 유형 임에도 불구하고) 이와 같은 확장 유형을 추가 할 수 없습니다.
누구든지 해결 방법을 알고 있습니까?
답변
편집 : 이것은 이제 UnconstrainedMelody의 0.0.0.2 버전에 있습니다.
( enum 제약 조건에 대한 내 블로그 게시물 에서 요청한대로 . 독립형 답변을 위해 아래 기본 사실을 포함했습니다.)
가장 좋은 해결책은 UnconstrainedMelody 1 에 포함시킬 때까지 기다리는 것입니다 . 이것은 다음과 같은 “가짜”제약 조건이있는 C # 코드를 사용하는 라이브러리입니다.
where T : struct, IEnumConstraint
그리고 그것을
where T : struct, System.Enum
빌드 후 단계를 통해.
작성하기가 너무 어렵지 않아야 IsSet
합니다. Int64
기반 및 UInt64
기반 플래그 를 모두 처리 하는 것이 까다로운 부분이 될 수 있지만. (기본적으로 UInt64
.
전화를 걸면 어떤 행동을 원하십니까?
tester.IsSet(MyFlags.A | MyFlags.C)
? 지정된 모든 플래그가 설정 되었는지 확인해야합니까 ? 그것이 내 기대입니다.
오늘 밤 집으로가는 길에이 작업을 수행해 보겠습니다. 라이브러리를 사용 가능한 표준에 빠르게 맞추고 잠시 휴식을 취하기 위해 유용한 enum 메서드에 대한 빠른 블리츠를 기대하고 있습니다.
편집하다 : 그건 IsSet
그렇고, 이름이 확실하지 않습니다 . 옵션 :
- 포함
- 포함
- HasFlag (또는 HasFlags)
- IsSet (확실히 옵션 임)
생각을 환영합니다. 어차피 결정이 내려지기까지는 시간이 좀 걸릴 거라고 확신 해요 …
1 또는 패치로 제출하십시오.
답변
C # 7.3부터는 enum 제약 조건을 추가하는 기본 제공 방법이 있습니다.
public class UsingEnum<T> where T : System.Enum { }
답변
Darren, 유형이 특정 열거 형이면 작동합니다. 일반 열거 형이 작동하려면 부울 수학을 수행하기 위해 int (또는 더 가능성이 높은 uint)로 캐스팅해야합니다.
public static bool IsSet( this Enum input, Enum matchTo )
{
return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
}
답변
사실 추악한 속임수로 가능합니다. 그러나 확장 방법에는 사용할 수 없습니다.
public abstract class Enums<Temp> where Temp : class {
public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
return (TEnum)Enum.Parse(typeof(TEnum), name);
}
}
public abstract class Enums : Enums<Enum> { }
Enums.IsSet<DateTimeKind>("Local")
원하는 경우 as를 사용 Enums<Temp>
하여 개인 생성자 및 공용 중첩 추상 상속 클래스를 제공하여 비 열거 형에 대한 상속 된 버전을 방지 할 수 있습니다.Temp
Enum
답변
IL Weaving 및 ExtraConstraints를 사용하여이를 달성 할 수 있습니다.
이 코드를 작성할 수 있습니다.
public class Sample
{
public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
{
}
public void MethodWithEnumConstraint<[EnumConstraint] T>()
{
}
}
컴파일되는 항목
public class Sample
{
public void MethodWithDelegateConstraint<T>() where T: Delegate
{
}
public void MethodWithEnumConstraint<T>() where T: struct, Enum
{
}
}
답변
C # 7.3부터는 제네릭 형식에 대해 Enum 제약 조건을 사용할 수 있습니다.
public static TEnum Parse<TEnum>(string value) where TEnum : Enum
{
return (TEnum) Enum.Parse(typeof(TEnum), value);
}
Nullable 열거 형을 사용하려면 원래 구조체 제약 조건을 그대로 두어야합니다.
public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
{
if( Enum.TryParse(value, out TEnum res) )
return res;
else
return null;
}