일반 예외 클래스의 모든 변형을 잡고 싶습니다. 여러 catch 블록없이 수행 할 수있는 방법이 있는지 궁금합니다. 예를 들어 예외 클래스가 있다고 가정 해보십시오.
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
그리고 2 개의 파생 클래스 :
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
모두 잡는 방법이있다 MyDerivedStringException
및 MyDerivedIntException
하나 개의 catch 블록은.
나는 이것을 시도했다 :
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
그러나 그것은 매우 깨끗하지 않으며 내가 액세스 할 수 없음을 의미합니다 MyProperty
.
나는 문제에 대한 일반적인 해결책에 관심이 있지만 내 경우에는 일반적인 지적 예외가 타사 라이브러리에 정의되어 있으며 아래 지적 된 것처럼 문제에 대한 추가 제약 조건이 추가되었습니다.
답변
확인 MyException<T>
인터페이스를 구현하고 인터페이스 유형에 의해 예외를 확인하십시오.
상호 작용:
public interface IMyException
{
string MyProperty { get; }
}
인터페이스를 구현하는 일반 클래스 :
public class MyException<T> : Exception, IMyException
{
public string MyProperty { get; }
public MyException(T prop)
{
MyProperty = prop?.ToString();
}
}
파생 클래스 :
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
용법:
try
{
// ...
}
catch (Exception e) when (e is IMyException)
{
// ...
}
동일은 기본 클래스를 생성하여 수행 할 수있는 상속에서 Exception
와 만드는 것보다 MyException<T>
그 기본 클래스에서 파생합니다.
답변
귀하 Type
가 일반에서 파생 된 경우의 테스트 는 다음과 같습니다.
Type = typeof(something);
t.GetGenericTypeDefinition()==typeof(MyException<>);
그러나 이것은 MyException<int>
또는 같은 파생 유형 자체에만 해당됩니다 MyException<string>
.
다음과 같이 추가 파생 상품이있는 경우 다음 MyDerivedStringException
을 테스트해야합니다.
ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>);
따라서 이것은 모든 일반 제네릭에 적용되지만이 테스트의 상속 수준을 알고 있거나 모든 기본 유형을 반복해야합니다.
그래서 당신은 이것을 할 수 있습니다 :
catch(Exception ex) when (ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>))
답변
이 구현은 T : Value가 Valuetype … 인 경우 상자를 열고 상자를 풉니 다. 그러나 사용률과 관련하여 상자 / 상자를 풀려고 시도하는 횟수로 성능 관련 사항을 제어 할 수 있습니다.
public class MyException<T> : MyException
{
public T Prop => (T)base.Prop;
public MyException(T prop) : base(prop)
{
}
}
public class MyException : Exception
{
protected object Prop { get; }
public MyException(object prop)
{
Prop = prop;
}
}
논리
try {
...
} catch(MyException e) {
...
}
답변
불행히도, 당신은 따라 잡을 수 없습니다
catch(MyException ex)
유형을 기대하는 클래스.
가장 좋은 방법은 기본 클래스 또는 인터페이스를 작성하고 잡아서 유형을 얻는 것입니다.
에 대한 답변 이미 있습니다 그래서 여기 유형을 얻을이 작업을 수행하는 방법은.
답변
이 구현은 예외 유형에 대한 처리 대의원을 T / C의 맥락에서 멀리 추상화합니다. 이것은 다소 모험적 일 수 있지만 멋진 부분은 재사용 범위와 문맥에 따라 다른 핸들러를 주입 할 수 있다는 것입니다. 이용.
public interface IExceptionHandler
{
object Handle(Exception ex);
void RegisterExceptionTypeHandler<T>(Func<T,object> handlerDelegate) where T : Exception;
}
등록 논리
handler.RegisterExceptionTypeHandler<MyException<int>>(ex => ...);
handler.RegisterExceptionTypeHandler<MyException<string>>(ex => ...);
try {
...
}catch(Exception ex)
{
...any validation
return exceptionHandler.Handle(ex)
}