2013-12-18 10 views
30

Ich habe eine Klasse enthält also eine Ausnahme, so.Überschreiben Sie die 'ist' Funktionalität

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

Ich möchte das außer Kraft setzen 'ist' Aktion, also anstatt das zu tun, so

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

Ich werde tun, so

if (ex is Validator.ValidatorException) 

Ist es möglich? Wie?

+7

Sie können entfernen Sie den '== true' Teil ohnehin seit Ihrem' Is' Methode a gibt ' bool'. Auch der Methodenname gibt an, dass der Rückgabewert ein boolescher Wert wäre, so dass es nicht notwendig ist, ihn durch eine explizite Überprüfung auf "wahr" zu klären. –

+3

Es ist nicht cool, Typen durch den Vergleich ihrer Namenszeichenfolgen zu vergleichen.Die übliche Vorgehensweise ist 'a is MyType', wenn Sie testen möchten, ob' a' einen Laufzeittyp hat, der mit 'MyType' durch Vererbung (einschließlich Boxing/Unboxing) oder generische Varianz kompatibel ist. Wenn Sie nach einem genauen Laufzeittyp suchen möchten, verwenden Sie stattdessen 'a! = Null && a.GetType() == typeof (MyType)'. Wie gesagt, vergleiche keine Strings. –

+0

@Jeppe Ich kann den ursprünglichen Typ des Fehlers nicht erhalten, da es in dieser Wrapper-Klasse über WCF übertragen wird. – Yacov

Antwort

50

Von Overloadable Operators können die folgenden Operatoren überlastet werden:

  • Unary: +, -, !, ~, ++, --, true, false
  • Binary: +, -, *, /, %, &, |, ^, <<, >>
  • Vergleich: ==, !=, <, >, <=, >=

Und diese Betreiber können nicht überlastet werden:

  • Logisch: &&, ||
  • Array Indizierung: []
  • Darsteller: (T)x
  • Aufgabe: +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • Andere: =, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof

Auch Vergleichsoperatoren müssen paarweise überlastet werden, wenn Sie Überlasten Sie einen, müssen Sie den anderen überlasten:

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

IMHO, "ist! = Ist". Es ist, als würde man eine neue Funktion 'Is()' erstellen und den Operator 'is' nicht überladen. Korrigiere mich, wenn ich falsch liege. –

+1

Seit wann kann man den Cast-Operator nicht überladen? [Explizit] (https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx) und [implizit] (https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx) – JPVenson

12

is ist ein nicht-überladene Schlüsselwort, aber Sie können Erweiterungen Methode wie folgt schreiben:

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

Wie ist Ihr Beispiel nützlich? Das Sagen von 'mySource.Is ()' ist nicht schöner, als zu sagen, dass "mySource MyType" ist. Eine andere Frage: Warum würden Sie auf "Klassen" beschränken, d. H. Referenztypen? –

+0

ist nützlich, da die Methode das Objekt erweitert und für jedes Objekt aufgerufen werden kann. Es ist daher üblich. Eingeschränkt auf die Klasse ist vielleicht unnötig, ein Beispiel, das ich aus einem Projekt kopiert habe, wo ich diese Einschränkung brauchte. – Davecz

+2

Ich verstehe es nicht. Wenn du den Code 'var myCar = new Car() hast; bool test = myCar ist Giraffe; 'und keiner der Typen' Car' und 'Giraffe' ist ein Interface-Typ, dann wenn' Car' nicht in der Vererbungskette von 'Giraffe' und' Giraffe' nicht in der Erbschaft ist Kette von 'Car', dann führt das' is' Schlüsselwort zu einer Kompilierungswarnung. Aber das ist eine gute Sache. Du könntest das mit '(object) myCar is Giraffe' umgehen, oder mit deiner Extension, aber der Wert ist immer noch' false'. Also ist 'is' besser als die Verwendung Ihrer Erweiterung. –

34

der geraden Antwort ist: Nein, is kann nicht überschrieben werden (weil es ein Schlüsselwort ist).

Aber Sie könnten etwas eleganter tun, indem Sie Generika verwenden. Definieren Sie zunächst Ihre Is() Methode wie folgt:

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

Dann können Sie Ihren Vergleich wie folgt schreiben:

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