[c#] 잘못된 제네릭 형식 인수에 대한 최상의 예외

현재 열거 형과 관련된 일반적인 메서드가있는 UnconstrainedMelody에 대한 코드를 작성 중 입니다.

이제 “플래그”열거 형 에만 사용되는 메서드가 포함 된 정적 클래스가 있습니다. 나는 이것을 제약 조건으로 추가 할 수 없으므로 다른 열거 형 유형으로도 호출 될 수 있습니다. 이 경우 예외를 던지고 싶지만 어떤 예외를 던질 지 잘 모르겠습니다.

이것을 구체적으로 만들기 위해 다음과 같은 것이 있으면 :

// Returns a value with all bits set by any values
public static T GetBitMask<T>() where T : struct, IEnumConstraint
{
    if (!IsFlags<T>()) // This method doesn't throw
    {
        throw new ???
    }
    // Normal work here
}

던지기에 가장 좋은 예외는 무엇입니까? ArgumentException논리적으로 들리지만 일반적인 인수가 아닌 유형 인수 이므로 쉽게 혼동 될 수 있습니다. 내 TypeArgumentException수업을 소개해야하나요 ? 사용 InvalidOperationException? NotSupportedException? 다른 건 없나요?

나는 것 보다는 그것을 분명히 옳은 일이 아니면이 내 자신의 예외를 만들 수 없습니다.



답변

NotSupportedException 분명히 맞는 것처럼 들리지만 문서에는 다른 목적으로 사용해야한다고 분명히 명시되어 있습니다. MSDN 클래스 비고에서 :

기본 클래스에서 지원되지 않는 메서드가 있으며 이러한 메서드는 대신 파생 클래스에서 구현 될 것으로 예상됩니다. 파생 클래스는 기본 클래스에서 메서드의 하위 집합 만 구현하고 지원되지 않는 메서드에 대해서는 NotSupportedException을 throw 할 수 있습니다.

물론 NotSupportedException, 특히 상식적인 의미를 고려할 때 분명히 충분히 좋은 방법이 있습니다. 그렇게 말했지만 그것이 옳은지 잘 모르겠습니다.

Unconstrained Melody 의 목적을 감안할 때 …

“T : enum”또는 “T : delegate”의 형식 제약 조건이있는 제네릭 메서드 / 클래스로 수행 할 수있는 다양한 유용한 작업이 있지만 불행히도 C #에서는 금지되어 있습니다.

이 유틸리티 라이브러리는 ildasm / ilasm …

… 그것은 Exception우리가 관습을 만들기 전에 당연히 만나야 만하는 증명의 높은 부담에도 불구하고 새로운 순서가 될 것 같습니다 Exceptions. InvalidTypeParameterException라이브러리 전체에서 다음 과 같은 것이 유용 할 수도 있습니다 (또는 그렇지 않을 수도 있습니다. 이건 확실히 엣지 케이스 죠?).

클라이언트가이를 BCL 예외와 구별 할 수 있어야합니까? 클라이언트가 실수로 바닐라를 사용하여 이것을 언제 호출 할 수 enum있습니까? 사용자 지정 예외 클래스를 작성할 때 고려해야 할 요소는 무엇입니까? 에 대한 허용 된 답변에 의해 제기 된 질문에 어떻게 대답 하시겠습니까?


답변

NotSupportedException을 피할 것입니다. 이 예외는 메서드가 구현되지 않은 프레임 워크에서 사용되며이 유형의 작업이 지원되지 않음을 나타내는 속성이 있습니다. 여기에 맞지 않습니다

InvalidOperationException이 여기서 던질 수있는 가장 적절한 예외라고 생각합니다.


답변

일반 프로그래밍은 유효하지 않은 유형 매개 변수에 대해 런타임에 발생하지 않아야합니다. 컴파일해서는 안되며 컴파일 시간을 시행해야합니다. 무엇이 IsFlag<T>()포함되어 있는지 모르겠지만 아마도 이것을 ‘플래그’로만 생성 할 수있는 유형을 생성하려는 것과 같이 컴파일 시간 적용으로 전환 할 수 있습니다. 아마도 traits클래스는 도움이 될 수 있습니다.

최신 정보

당신이 경우 해야한다 던지, 내가 InvalidOperationException이 투표 것입니다. 그 이유는 제네릭 형식에는 매개 변수가 있고 (메서드) 매개 변수 와 관련된 오류는 ArgumentException 계층을 중심으로 이루어지기 때문입니다. 그러나 ArgumentException에 대한 권장 사항 에 따르면

실패가 인수 자체를 포함하지 않는 경우 InvalidOperationException을 사용해야합니다.

메서드 매개 변수 권장 사항이 일반 매개 변수 에도 적용 된다는 믿음이 적어도 한 번 있습니다 . 그러나 SystemException 계층 구조 imho에는 더 나은 것이 없습니다.


답변

나는 당신이 말하는 것처럼 NotSupportedException을 사용할 것입니다. 특정 열거 형 이외의 다른 열거 형은 지원되지 않습니다 . 물론 이것은 예외 메시지에서 더 명확하게 설명됩니다.


답변

나는 함께 갈 것이다 NotSupportedException. 하지만 ArgumentException방법에 전달 된 인수가 받아 들일 때 외모 벌금, 그것은 정말 예상됩니다. 형식 인수는 실제 “인수”가 아니라 호출하려는 실제 메서드에 대한 정의 특성입니다. InvalidOperationException수행중인 작업이 일부 경우에 유효 할 수 있지만 특정 상황에서는 허용되지 않을 때 throw되어야합니다.

NotSupportedException작업이 본질적으로 지원되지 않을 때 발생합니다. 예를 들어, 특정 멤버가 클래스에 적합하지 않은 인터페이스를 구현할 때. 이것은 비슷한 상황처럼 보입니다.


답변

Microsoft는 예외 섹션 ArgumentExceptionExpression.Lambda <> , Enum.TryParse <> 또는 Marshal.GetDelegateForFunctionPointer <> 예제 에서 설명한 것처럼이를 사용 합니다. ( TDelegate및에 대한 로컬 참조 소스를 검색했지만) 그렇지 않은 경우를 나타내는 예를 찾을 수 없습니다 TEnum.

따라서 최소한 Microsoft 코드에서는 ArgumentException기본 변수 외에 잘못된 제네릭 형식 인수 를 사용하는 것이 일반적인 관행이라고 가정하는 것이 안전하다고 생각합니다 . 문서 의 예외 설명 이 이들을 구별하지 않는다는 점을 감안할 때 너무 무리가 아닙니다.

바라건대 그것은 질문을 단번에 결정합니다.


답변

NotSupportedExpcetion으로 이동합니다.