2013-12-18 87 views
30

我有一個類,因此包含異常。重寫'is'功能

public class ExceptionWrapper 
{ 
    public string TypeName { get; set; } 
    public string Message { get; set; } 
    public string InnerException { get; set; } 
    public string StackTrace { get; set; } 

    public ExceptionWrapper() { } 

    public ExceptionWrapper(Exception ex) 
    { 
     TypeName = String.Format("{0}.{1}", ex.GetType().Namespace, ex.GetType().Name); 
     Message = ex.Message; 
     InnerException = ex.InnerException != null ? ex.InnerException.Message : null; 
     StackTrace = ex.StackTrace; 
    } 

    public bool Is(Type t) 
    { 
     var fullName = String.Format("{0}.{1}", t.Namespace, t.Name); 
     return fullName == TypeName; 
    } 
} 

我想覆蓋 '是' 的動作,所以不是這樣

if (ex.Is(typeof(Validator.ValidatorException)) == true) 

我會這樣做

if (ex is Validator.ValidatorException) 

這可能嗎?怎麼樣?

+7

您仍然可以刪除'== TRUE'一部分,因爲你'Is'方法返回一個' bool'。此外,方法名稱指示返回值將是布爾值,因此不需要通過顯式檢查「true」來澄清它。 –

+3

通過比較類型名稱來比較類型並不酷。如果要通過繼承(包括裝箱/拆箱)或通用方差來測試'a'是否具有與'MyType'兼容的運行時類型,通常要做的就是'a是MyType'。如果你想檢查一個確切的運行時類型,改用'a!= null && a.GetType()== typeof(MyType)'。正如我所說,不要比較字符串。 –

+0

@Jeppe我無法獲得錯誤的原始類型,因爲它是通過WCF在此包裝類中傳輸的。 – Yacov

回答

50

Overloadable Operators,下面的操作符可以被重載:

  • 一元:+, -, !, ~, ++, --, true, false
  • 二進制:+, -, *, /, %, &, |, ^, <<, >>
  • 比較:==, !=, <, >, <=, >=

而且這些運營商不能超載:

  • 邏輯:&&, ||
  • 數組索引:[]
  • 演員:(T)x
  • 分配:+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • 其他:=, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof

此外,比較運營商需要在對超載,如果你超載一臺,必須超載另一臺:

  • ==!=
  • <>
  • <=>=
+4

恕我直言,'是!= is'。這就像創建一個新的函數Is()並且不會重載is is運算符。糾正我,如果我錯了。 –

+1

既然你不能重載Cast操作符? [explicit](https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx)和[implicit](https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx) – JPVenson

12

is是一種非超載的關鍵字,但您可以編寫擴展方法是這樣的:

public static bool Is<T>(this Object source) where T : class 
{ 
    return source is T; 
} 
+4

你的例子有用嗎?說'mySource.Is ()'不比說'mySource是MyType'好。另一個問題:爲什麼你會限制'class',即引用類型? –

+0

很有用,因爲該方法擴展了對象並可以在任何對象上調用。因此很常見。僅限於課程可能是不必要的,我從我需要此限制的項目中複製了一個示例。 – Davecz

+2

我不明白。如果你有代碼'var myCar = new Car(); bool test = myCar是長頸鹿;',而'Car'和'Giraffe'都不是接口類型,那麼如果'Car'不在'Giraffe'的繼承鏈中,'Giraffe'不在繼承中'Car'鏈,那麼'is'關鍵字會導致編譯時警告。但這是一件好事。你可以用'(object)myCar是Giraffe'來解決這個問題,或者用你的擴展名來解決這個問題,但是它的值始終是'false'。所以使用'is'比使用擴展名更好。 –

34

直回答是:不,is不能被覆蓋(因爲它是關鍵字)。

但是你可以通過使用泛型來做更優雅的事情。首先定義你的Is()方法,像這樣:

public bool Is<T>() where T: Exception 
{ 
    return typeof(T).FullName == this.TypeName; 
} 

然後,你可以寫你的比較是這樣的:

if (ex.Is<Validator.ValidatorException>())