25

가능한 중복 :

누구나 열거 형 제네릭 제약의 부족에 대한 좋은 해결 방법을 알고 있습니까?

T를 Enum으로 제한하는 일반 메소드 생성

제네릭 형식 매개 변수를 제한 할 수 있습니까? [올바른 이름인지는 모릅니다.]Enum?

예를 들어 어떻게하면 이렇게 할 수 있습니까?

//VB.NET
Function GetValues(Of T As System.Enum)(ByVal value As T) As IEnumerable(Of T)
    Return [Enum].GetValues(value.GetType)
End Function

//C#
public IEnumerable<T> GetValues<T>(T value) where T : System.Enum
{
    return Enum.GetValues(value.GetType());
}

최신 정보

나는 결국 Jon Skeet을 사용했다.제한되지 않은 멜로디그 목적을 위해. 귀하의 모든 공헌에 감사드립니다.


4 답변


7

불행히도, 당신은 할 수 없습니다 -Microsoft는 항목을 수정하지 않으므로이 항목을 종료했습니다..

열거 형을 구조체로 취급하고이를 제약 조건으로 사용할 수 있습니다 (Jon Skeet이 어떻게했는지 생각합니다.)제한되지 않은 멜로디?)하지만 그건보기 흉한 것입니다.


  • Jon Skeet의 Unconstrained Melody를 알려 주셔서 감사합니다. 그것은 매우 도움이되었습니다. - Alex Essilfie
  • 링크가 끊어졌습니다. - AbleArcher
  • C # 7.3은 실제로 열거 형에 의한 일반적인 제한을 제한하는 기능을 추가했습니다.출처 - Tyler Gill

16

당신은 할 수 없습니다. 대체 솔루션으로struct및 런타임 검사.

public IEnumerable<T> GetValues<T>(T value) where T : struct
{  
    if (!typeof(T).IsEnum) throw new NotSupportedException();
    return (IEnumerable<T>)Enum.GetValues(value.GetType()); 
} 


  • 컴파일하는 경우에도 원하는 결과가 반환되지 않습니다.Enum.GetValues~을 돌려 준다.Array(그 요소는 단지 객체들입니다), 암묵적으로IEnumerable<T>. - KeithS
  • 불행히도 솔루션은 일반적인 열거 가능 목록을 반환하지 않습니다. 그것은 약간의 통찰력으로 나에게 제공했다. 감사. - Alex Essilfie
  • 제쳐두고 저는 솔루션을 구현했습니다.@ Keiths & # 39;관련이 있지만 목적은 다르다. - Alex Essilfie

5

Matt 's와 Danny의 답변은 모두 절반의 대답을 가지고 있습니다. 이렇게하면 실제로 필요한 것을 얻을 수 있습니다.

public IEnumerable<T> GetValues<T>() where T : struct
{   
    if (!typeof(T).IsEnum) throw new InvalidOperationException("Generic type argument is not a System.Enum");
    return Enum.GetValues(typeof(T)).OfType<T>(); 
} 

Danny의 답변에서 변경된 사항 :

  • 제네릭 형식의 매개 변수를 사용하면 형식 유추가 가능하지만 값이 실제로 사용되지 않으므로 매개 변수를 사용하지 않는 Linq 메서드와 같이 제네릭 형식을 명시 적으로 지정하는 것이 더 적합합니다.
  • Enum.GetValues ()는 T의 IEnumerable에 암시 적으로 캐스트되지 않는 객체의 배열을 반환합니다. 결과를 캐스팅하는 추가 Linq 메서드 (기술적으로 OfType은 필터 연산이지만이 경우 모든 것을 반환 함)는 반환 유형에 부합해야합니다.
  • 선택 사항 : NotSupportedException이 예외를 throw하는 데 좋은 선택이지만 다른 옵션이 있습니다. ArgumentException, InvalidOperationException, InvalidCastException 등이 있습니다. InvalidOperationException을 선택한 이유는 무엇입니까? 비 enum 유형에서 enum 값을 가져 오는 잘못된 시도. 이것은 의미 론적이며 다른 누구의 논리와도 논쟁하지 않을 것입니다.


  • 왜 캐스트 방법을 사용하지 않는 것이 좋을까요?return Enum.GetValues(typeof(T)).Cast<T>() - Metro Smurf
  • 이 경우 아마 작동 할 것입니다. 그러나 사용자가 기대하는 방식으로 작동하지 않는 경우를 다루는이 사이트에 대한 몇 가지 질문이 있습니다. OfType 또는 Select를 선호하여 명확한 방식으로 작업을 수행하는 것을 선호합니다. - KeithS
  • 제쳐두고 저는 솔루션을 구현했습니다.@ 대니 첸관련이 있지만 목적은 다르다. - Alex Essilfie

2

이 방법으로 일반적인 방법을 만들 필요가 없습니다.

당신은 단지System.Enum반환 유형에 type 매개 변수로 :

using System.Linq;
.
.
.
public IEnumerable<Enum> GetValues(Enum value)
{
    return Enum.GetValues(value.GetType()).OfType<Enum>();
}


  • 유감스럽게도 이것은 전달 된 Enum에 강력하게 입력되지 않았습니다. 적절한 유형으로 변환해야하는 System.Enum을 포함하는 목록을 얻습니다. - KeithS
  • @KeithS : 대니 첸 (Danny Chen)의 대답과 OP의 원래 코드 (예 : 실제로는 작동하지 않습니다.Array제네릭은 아닙니다). - Matt Ellen
  • 아니요. 제네릭은 해당 열거 형의 값 목록을 강력하게 형식화 한 목록을 반환합니다. 반환 형식의 캐스팅은 필요하지 않습니다 (숫자 또는 문자열 등을 원한다면 제외). 그러나 다른 이유로 그 사람은 일하지 않습니다. - KeithS

연결된 질문


관련된 질문

최근 질문