문제

맞아요, 이걸 쓰면 제가 완전 바보처럼 보일 거라는 걸 알지만, 제 뇌는 그저 ~ 아니다 오늘 아침에 장비를 시작합니다.

"나쁜 일이 생기면 이런 예외를 가지고 돌아오세요"라고 말할 수 있는 방법을 갖고 싶습니다. 그렇죠?

예를 들어, (그리고 이건 작동하지 않아):

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = new Exception(message);
        return ex;
    }

이제 나를 혼란스럽게 만드는 것은 우리가 알다 일반 유형은 다음으로 인해 예외 유형이 될 것입니다. 어디 절.그러나 암시적으로 캐스팅할 수 없기 때문에 코드가 실패합니다. 예외 에게 Ex 유형.다음과 같이 명시적으로 변환할 수도 없습니다.

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        Exception ex1 = new Exception();
        ExType ex = (ExType)(new Exception(message));
        return ex;
    }

그것도 실패하니까..그래서 이런 일이 가능한가요? 정말 간단할 것 같다는 강한 느낌이 들지만, 그 늙은 노긴 때문에 힘든 하루를 보내고 있으니 조금만 여유를 가지세요 :P


업데이트

답변해주셔서 감사합니다. 제가 그런 역할을 한 것은 아닌 것 같습니다. 완벽한 바보!;)

알았어 그래서 베가드 그리고 올바른 유형을 인스턴스화할 수 있는 지점까지 도달했지만 분명히 막혔습니다. 메시지 param은 인스턴스화 이후 읽기 전용입니다.

매트 그의 반응으로 머리에 바로 못을 박았습니다. 나는 이것을 테스트했고 모든 것이 잘 작동합니다.예제 코드는 다음과 같습니다.

    static ExType TestException<ExType>(string message) where ExType:Exception, new ()
    {
        ExType ex = (ExType)Activator.CreateInstance(typeof(ExType), message);
        return ex;
    }

달콤한!:)

고마워요!

도움이 되었습니까?

해결책

거의 다음과 같이 할 수 있습니다.

static void TestException<E>(string message) where E : Exception, new()
{
    var e = new E();
    e.Message = message;
    throw e;
}

그러나 Exception.Message는 읽기 전용이므로 컴파일되지 않습니다.생성자에 전달해야만 할당할 수 있으며 기본 생성자 이외의 다른 것으로 제네릭 형식을 제한할 수 있는 방법이 없습니다.

다음과 같이 메시지 매개변수가 포함된 사용자 정의 예외 유형을 "새로 만들기" 위해 리플렉션(Activator.CreateInstance)을 사용해야 한다고 생각합니다.

static void TestException<E>(string message) where E : Exception
{
    throw Activator.CreateInstance(typeof(E), message) as E;
}

편집하다 이런, 방금 당신이 원하는 걸 깨달았어요 반품 예외는 던지지 마세요.동일한 원칙이 적용되므로 throw 문에 대한 대답은 그대로 두겠습니다.

다른 팁

이 솔루션의 유일한 문제는 단일 문자열 매개변수를 사용하여 생성자를 구현하지 않는 Exception의 하위 클래스를 생성할 수 있어 MethodMissingException이 발생할 수 있다는 것입니다.

static void TestException<E>(string message) where E : Exception, new()
{
    try 
    {
      return Activator.CreateInstance(typeof(E), message) as E;
    } 
    catch(MissingMethodException ex) 
    {
      return new E();
    }
}

나는 다음과 같이 던지고 싶은 예외 유형을 인라인으로 인스턴스화했습니다.

if (ItemNameIsValid(ItemName, out errorMessage))
    throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
if (null == MyArgument)
    throw new ArgumentNullException("MyArgument is null");

대신 시도해 보셨나요?

static T TestException<Exception>(string message)
{}

던질 수 있는 모든 예외처럼 일반 제약 조건을 넣을 필요가 없다고 생각하기 때문입니다. ~ 해야 하다 어쨌든 System.Exception에서 상속됩니다.

제네릭은 상속된 유형을 허용한다는 점을 기억하세요.

제 생각엔 모든 예외에는 매개변수가 없는 생성자가 있어야 하고 Message 속성이므로 다음이 작동합니다.

static ExType TestException<ExType>(string message) where ExType:Exception
{
    ExType ex = new ExType();
    ex.Message = message;
    return ex;
}

편집하다:좋습니다. 메시지는 읽기 전용이므로 클래스가 대신 Exception(string) 생성자를 구현하기를 바랍니다.

static ExType TestException<ExType>(string message) where ExType:Exception
{
    return new ExType(message);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top