2013-12-18 10 views
30

Mam klasy, więc zawiera wyjątek, tak jak.Zastępowanie funkcji "jest"

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

Chcę zastąpić działania 'jest', więc robią tak

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

zamiast Zrobię tak

if (ex is Validator.ValidatorException) 

Czy to możliwe? W jaki sposób?

+7

można usunąć '== TRUE udział w każdym razie, ponieważ Twój' metoda Is' zwraca ' bool'. Również nazwa metody wskazuje, że zwracana wartość będzie wartością boolowską, więc nie ma potrzeby jej wyjaśniania poprzez jawne zaznaczenie "true". –

+3

Nie jest fajnie porównywać typy poprzez porównywanie ich łańcuchów nazw.Zwykle jest to 'a to MyType', jeśli chcesz przetestować, czy' a' ma działający typ kompatybilny z 'MyType' poprzez dziedziczenie (włączając w to boxing/unboxing) lub ogólną wariancję. Jeśli chcesz sprawdzić dokładny typ działania, użyj zamiast niego 'a! = Null && a.GetType() == typeof (MyType)'. Jak już powiedziałem, nie porównuj ciągów. –

+0

@Jeppe Nie mogę uzyskać oryginalnego typu błędu, ponieważ jest to transfer w tej klasie opakowania za pośrednictwem WCF. – Yacov

Odpowiedz

50

Od Overloadable Operators, następujące podmioty mogą być przeciążone:

  • Jednoargumentowy: +, -, !, ~, ++, --, true, false
  • Binary: +, -, *, /, %, &, |, ^, <<, >>
  • Porównanie: ==, !=, <, >, <=, >=

A te podmioty nie mogą być przeciążone:

  • Logical: &&, ||
  • Array indeksowania: []
  • Obsada: (T)x
  • Zadanie: +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
  • Inne: =, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof

również operatory porównania muszą być przeładowany w parach, jeśli ciebie przeciąż jeden, musisz przeciążyć drugi:

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

IMHO, 'Is! = Is'. Jest to jak tworzenie nowej funkcji 'Is()' i nie przeciążanie operatora 'is'. Popraw mnie, jeśli się mylę. –

+1

Od kiedy nie można przeciążać operatora Cast? [jawne] (https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx) i [ukryte] (https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx) – JPVenson

12

is jest non-przeładowany słów kluczowych, ale można napisać przedłużeń metodę tak:

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

Jaki jest twój przykład przydatny? Powiedzenie 'mySource.Is ()' nie jest ładniejsze niż powiedzenie 'mySource to MyType'. Kolejne pytanie: dlaczego miałbyś ograniczać "klasy", tj. Typy odniesienia? –

+0

jest przydatny, ponieważ metoda rozszerza obiekt i może być wywołana na dowolnym obiekcie. Jest więc powszechne. Ograniczenie do klasy jest prawdopodobnie niepotrzebne, przykład skopiowałem z projektu, w którym potrzebowałem tego ograniczenia. – Davecz

+2

Nie rozumiem. Jeśli masz kod 'var myCar = new Car(); bool test = myCar to żyrafa; ', a żaden z typów' Car' i 'Giraffe' nie jest typem interfejsu, to jeśli' Car' nie jest w łańcuchu dziedziczenia 'Giraffe' i' Giraffe' nie jest dziedziczone łańcuch 'Car', a następnie słowo kluczowe' is' prowadzi do ostrzeżenia o kompilacji. Ale to dobrze. Można to obejść za pomocą '(object) myCar to Giraffe' lub z twoim rozszerzeniem, ale wartość będzie zawsze" false "zawsze. Więc użycie 'jest' jest lepsze niż użycie twojego rozszerzenia. –

34

Prosta odpowiedź brzmi: Nie, is nie można nadpisać (ponieważ jest to słowo kluczowe).

Ale można zrobić coś bardziej eleganckiego za pomocą generycznych. Najpierw zdefiniować metodę Is() tak:

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

Następnie można napisać porównanie takiego:

if (ex.Is<Validator.ValidatorException>()) 
Powiązane problemy