2011-12-20 37 views
1

我创建一个异常类这样的:如何避免在以下代码中强制转换为(ServiceException)?

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) {} 

} 

下面的代码失败:

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); 
    } 
} 

它生成上编译以下错误:

错误5 'System.Exception的'不包含“错误” 的定义,并且没有接受 类型的第一个参数的扩展方法'Errors''System.Exception'c乌尔德找到(是否缺少using指令 或程序集引用?)

我通过以下操作固定它:

if (ex is ServiceException) 
{ 
    var y = (ServiceException)ex; 
    ModelState.Merge(y.Errors); 
} 

有一些办法,我可以使用避免这种乱码一个变量y然后铸造它?没有声明中间变量y,代码不会通过语法检查。

+2

你需要口齿不清讲:ModelState.Merge(((ServiceException)除息).Errors); – 2011-12-20 04:45:28

+0

在C#中,一种方法或者你必须使用一个强制转换来使编译器感到高兴。 – Roman 2011-12-20 04:47:02

回答

2

您需要投射,因为ex不是ServiceExceptionis运算符只是简单地评估它是否为ServiceException,但不会对该类型执行转换。

想想ex是什么类型。它的类型是Exception,一般来说你不知道它是什么。通过调用ex is ServiceException,您正在检查ex的动态类型是否为ServiceException。但静态类型仍然是Exception。这并没有改变。

C#是一种静态类型语言,所以你用is操作后静态ex,这是Exception不会魔术般地变成ServiceException。你仍然需要自己施放它。

相反,你可能希望使用的运营商:

protected void log(Exception ex) 
{ 
    ServiceException se = ex as ServiceException; 
    if (se != null) 
     ModelState.Merge(se.Errors); 
    else 
    { 
     Trace.Write(ex); 
     ModelState.AddModelError("", "Database access error: " + ex.Message); 
    } 
} 

ex as ServiceException尝试投exServiceException。如果ex不是ServiceException,则转换失败并返回null。

或者,如果你真的对使用额外的局部变量,那么你可以只投它,然后立即使用它:

if (se is ServiceException) 
    ModelState.Merge(((ServiceException) se).Errors); 

老实说,虽然,我不明白你为什么会想这虽然。首先执行检查(使用asis),然后使用经过降级的异常,这是此处最好的办法。实际使用额外的变量更清晰,因为您显示了您的意图,并且立即显而易见您想要实现的目标。

1

你需要投它,但你可以只是做内联:

if (ex is ServiceException) 
     { 
      ModelState.Merge(((ServiceException)ex).Errors); 
     } 

希望帮助:)

0

你将不得不投,只是说我会做不同的看法。

try 
    { 
    ... 
    } 
    catch(ServiceException ex) 
    { 
     logException(ex); 
    } 
    catch(Exception ex) 
    { 
     logException(ex); 
    } 

public void logException(ex) 
{ 
    if(ex is ServiceException) 
    { 
     logServiceException(ex as ServiceException) 
    } 
    else 
    { 
     logGenericException(ex) 
    } 
} 

private void logGenericException(Exception ex) 
{ 
... 
} 

没有必要在下面的方法来投

private void logServiceException(ServiceException ex) 
    { 
    //now there is no need to do a cast 
    } 
相关问题