I created an exception class like this:
public class ServiceException : ApplicationException {
public Dictionary<string, string> Errors { get; set; }
public ServiceException(Exception ex) : base("Service Exception", ex) {
Errors = new Dictionary<string, string>();
}
public ServiceException() : this(null) {}
}
The following code fails:
protected void log(Exception ex)
{
if (ex is ServiceException)
{
var y = (ServiceException)
ModelState.Merge(ex.Errors);
}
else
{
Trace.Write(ex);
ModelState.AddModelError("", "Database access error: " + ex.Message);
}
}
It generates the following error on compile:
Error 5 ‘System.Exception’ does not contain a definition for ‘Errors’
and no extension method ‘Errors’ accepting a first argument of type
‘System.Exception’ could be found (are you missing a using directive
or an assembly reference?)
I fixed it by doing the following:
if (ex is ServiceException)
{
var y = (ServiceException)ex;
ModelState.Merge(y.Errors);
}
Is there some way that I can avoid this messy code using a variable y and then casting it ? Without declaring the intermediate variable y the code does not pass a syntax check.
You need to cast because ex is not a
ServiceException. Theisoperator is simply evaluating telling you that it is aServiceException, but doesn’t perform the cast to the type.Think about what type ex is. It’s of type
Exception, and generally speaking you don’t know what it is. By callingex is ServiceException, you’re checking if the dynamic type ofexisServiceException. But the static type is stillException. That doesn’t change.C# is a statically typed language, so the static type of
ex, which isExceptionwon’t magically change toServiceExceptionafter you use theisoperator. You still need to cast it yourself.Rather, you may wish to use the as operator:
ex as ServiceExceptiontries to castexto aServiceException. Ifexisn’t aServiceException, the cast fails and it returns null.Alternatively, if you’re really against using an extra local variable, then you can just cast it and then use it immediately:
Honestly though, I don’t see why you’d want this though. Doing the check first (using
asoris) followed by using the downcasted exception is the best idea here. It’s cleaner to actually use the extra variable because you’re showing your intent and it’s immediately obvious what you want to achieve.