我想创建一个字典来存储异常和该异常的格式化程序。
Dictionary<Type, Func<Exception, ApiErrorResponse>>
我可以像这样直接将它们添加到字典中
Dictionary<Type, Func<Exception, ApiErrorResponse>> _exceptionFormatters =
new Dictionary<Type, Func<Exception, ApiErrorResponse>>
{
{
typeof(ValidationException),
ex =>
{
var e = ex as ValidationException;
return new ApiErrorResponse(HttpStatusCode.UnprocessableEntity, e.Errors);
}
},
{
typeof(NotFoundException),
ex =>
{
var e = ex as NotFoundException;
return new ApiErrorResponse(HttpStatusCode.NotFound, e.Message);
}
}
};
但是我想用通用AddExceptionFormatter
方法来做
public static void AddExceptionFormatter<T>(Func<T, ApiErrorResponse> Value) where T : Exception
{
if (_exceptionFormatters.ContainsKey(typeof(T)))
_exceptionFormatters[typeof(T)] = (Func<Exception, ApiErrorResponse>)Value;
else
_exceptionFormatters.Add(typeof(T), (Func<Exception, ApiErrorResponse>)Value);
}
这是我如何调用它。
AddExceptionFormatter<NotFoundException>(ex =>
{
return new ApiErrorResponse(
HttpStatusCode.NotFoundException,
nameof(NotFoundException),
ex.Message);
});
但是不幸的是我 Unable to cast object of type 'System.Func`2[NotFoundException,ApiErrorResponse]' to type 'System.Func`2[System.Exception,ApiErrorResponse]'.
任何想法我该如何投放Func<,>
?
该字典存储“即采取任何功能Exception
的”,但你给字典中“功能,采取具体Exception
是T
”。显然,“具有特定Exception
于的功能T
”不是一种“具有任何Exception
s的功能”。
为了弄清楚为什么它可以中断,请假设:
AddExceptionFormatter<NotFoundException>(x => x.Foo);
在哪里Foo
具有属性,NotFoundException
类型为ApiErrorResponse
。
现在,如果我做这个顽皮的事情:
_exceptionFormatters[typeof(NotFoundException)](new Exception())
显然,这可以通过类型检查,因为我可以将传递Exception
给Func<Exception, ApiErrorResponse>
,但Exception
实际上没有Foo
属性!这就是为什么您不允许演员。
这里的根本问题是,您不能向编译器保证“如果typeof(X)
是字典的键之一,_exceptionFormatters[typeof(X)]
则将是类型Func<X, ApiErrorResponse>
”。C#的类型系统不足以支持它。
当某人做上述调皮的行为时,您需要决定要发生什么。假设您想引发异常,则可以使用lambda:
public static void AddExceptionFormatter<T>(Func<T, ApiErrorResponse> Value) where T : Exception
{
_exceptionFormatters[typeof(T)] = x => Value((T)x);
}
这将导致InvalidCastException
引发。您当然可以在lambda中做更多的事情:
x => {
if (x is T t) {
return Value(t);
} else {
throw new YourCustomException("some custom message");
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句