2011-12-20 15 views
1

私はこのような例外クラスを作成しました:次のコードで(ServiceException)にキャストする必要性を避けるにはどうすればよいですか?

エラー5 'のSystem.Exception':それはコンパイルに次のエラーが発生し

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

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

} 

次のコードが失敗しました'エラー'の定義が含まれていません と拡張メソッドなし 'エラー' 型の最初の引数を受け入れる 'System.Exception' c私は、次の操作を行って、それを修正(?あなたがusingディレクティブ またはアセンブリ参照が不足している)

見つけることがウルド:

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

は、私が使用して、この厄介なコードを避けることができ、いくつかの方法があります変数yとそれをキャストしますか?中間変数yを宣言しなければ、コードは構文チェックに合格しません。

+2

:ModelState.Merge(((はServiceException)EX).Errorsを)。 –

+0

C#一方向でもどちらでも、コンパイラを幸せにするためにはキャストを使用する必要があります。 – Roman

答えて

2

exがServiceExceptionではないため、キャストする必要があります。 isオペレータは、それがServiceExceptionであると評価するだけですが、そのタイプへのキャストを実行しません。

どのタイプがexであるかを考えます。それはタイプExceptionであり、一般にあなたはそれが何であるかを知らない。 ex is ServiceExceptionを呼び出すと、exの動的タイプがServiceExceptionであるかどうかが確認されます。しかし、静的型はまだExceptionです。それは変わらない。

C#が静的型付け言語であるので、あなたはis演算子を使用した後Exceptionあるex静的タイプは、魔法の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 ServiceExceptionServiceExceptionexをキャストしようとします。 exServiceExceptionでない場合、キャストは失敗し、nullを返します。あなたは本当に余分なローカル変数を使用して反対している場合

あるいは、その後、あなたはそれをキャストすることができますし、すぐにそれを使用する:あなたがしたいと思う理由

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

を正直にかかわらず、私は表示されませんこれでも。最初にチェックを行い(asまたはisを使用)、ここでダウンキャストされた例外を使用することが最適です。あなたがあなたの意図を示しているので、実際に余分な変数を使用するのがよりクリーンです。それはすぐに達成したいことが明らかです。

1

あなたはそれをキャストする必要がありますが、あなただけのインラインそれを行うことができます:あなたは、私は違っそれを行うのと同じことを、キャストする必要があります:)

0

を助け

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

希望。

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 
    } 
関連する問題