program tip

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

radiobox 2020. 8. 24. 08:01
반응형

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


현재 열거 형과 관련된 일반적인 메서드가있는 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작업이 본질적으로 지원되지 않을 때 발생합니다. 예를 들어, 특정 멤버가 클래스에 적합하지 않은 인터페이스를 구현할 때. 이것은 비슷한 상황처럼 보입니다.


Apparently, Microsoft uses ArgumentException for that, as demonstrated on example of Expression.Lambda<>, Enum.TryParse<> or Marshal.GetDelegateForFunctionPointer<> in Exceptions section. I couldn't find any example indicating otherwise, either (despite searching local reference source for TDelegate and TEnum).

So, I think it's safe to assume that at least in Microsoft code it's a common practice to use ArgumentException for invalid generic type arguments aside from basic variable ones. Given that the exception description in docs doesn't discriminate between those, it's not too much of a stretch, either.

Hopefully it decides the question things once and for all.


Id go with NotSupportedExpcetion.


Throwing a custom made exception should always be done in any case where it is questionable. A custom exception will always work, regardless of the API users needs. The developer could catch either exception type if he does not care, but if the developer needs special handling he will be SOL.


How about inheriting from NotSupportedException. While I agree with @Mehrdad that it makes the most sense, I hear your point that it doesn't seem to fit perfectly. So inherit from NotSupportedException, and that way people coding against your API can still catch a NotSupportedException.


I'm always wary of writing custom exceptions, purely on the grounds that they aren't always documented clearly and cause confusion if not named correctly.

In this case I would throw an ArgumentException for the flags check failure. It's all down to preference really. Some coding standards I've seen go as far as to define which types of exceptions should be thrown in scenarios like this.

If the user was trying to pass in something which wasn't an enum then I would throw an InvalidOperationException.

Edit:

The others raise an interesting point that this is not supported. My only concern with a NotSupportedException is that generally those are the exceptions that get thrown when "dark matter" has been introduced to the system, or to put it another way, "This method must go into the system on this interface, but we won't turn it on until version 2.4"

I've also seen NotSupportedExceptions be thrown as a licensing exception "you're running the free version of this software, this function is not supported".

Edit 2:

Another possible one:

System.ComponentModel.InvalidEnumArgumentException  

The exception thrown when using invalid arguments that are enumerators.


I'd also vote for InvalidOperationException. I did an (incomplete) flowchart on .NET exception throwing guidelines based on Framework Design Guidelines 2nd Ed. awhile back if anyone's interested.

참고URL : https://stackoverflow.com/questions/1412598/best-exception-for-an-invalid-generic-type-argument

반응형