2010-10-03 10 views
24

Czy możesz podać przykład zastosowania wzoru "try" .NET?Przykładowa implementacja "TryParse" lub "TryGetValue"

Edit:

nie oznacza "try-catch" oświadczenie, mam na myśli wzorce próbować, jak te stosowane w TryParse() i TryGetObjectByKey() metod.

Przede wszystkim, co zrobić z podniesionymi wyjątkami w niestandardowych metodach wzorujących na "próbach". Czy powinienem to zarejestrować, czy powinienem to zignorować. Czy ktokolwiek wie, jaka jest praktyka z tymi metodami?

+8

Jeśli masz na myśli funkcję języka, a następnie quid pro quo: daj mi przykład, z którym próbowałem przeczytać dokumentację: http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80) .aspx –

+0

Masz na myśli instrukcję "try"/'catch'? ] (http://msdn.microsoft.com/en-us/library/0yd65esw.aspx) – kennytm

+2

następne pytanie: Proszę wyjaśnić wzór pustki? – vidalsasoon

Odpowiedz

32

Oto przykład pomocą sposób TryXxx:

string s = Console.ReadLine(); 
int x; 
if (int.TryParse(s, out x)) 
{ 
    Console.WriteLine("You entered the valid integer {0}", x); 
} 
else 
{ 
    Console.WriteLine("Invalid input!"); 
} 

Oto przykład określenie sposób:

bool TryParse(string s, out int x) // out parameter for result 
{ 
    if (!allCharactersAreValid(s)) 
    { 
     x = 0; 
     return false; 
    } 

    // More checks... 
    // Parse the string... 

    x = 42; 
    return true; 
} 

obsługi wyjątków

Większość specificly co zrobić z rised wyjątków w zwyczaju „próbować” metody wzór

Twoja metoda prawdopodobnie powinny unikać rzucania żadnych wyjątków - jeśli użytkownik chciał wyjątki będą używać non-Wypróbuj wersję. Dlatego powinieneś unikać metod wywoływania, które mogą rzucić podczas implementacji Twojego TryXxx. Jednak niektóre wyjątki są nieuniknione i mogą zostać odrzucone spod Twojej kontroli - na przykład OutOfMemoryException, StackOverflowException, itp ... Nic nie możesz na to poradzić i nie powinieneś próbować wychwycić tych wyjątków, po prostu pozwól im propagować do rozmówcy. Nie połykaj ich, nie rejestruj ich - to jest odpowiedzialność dzwoniącego.

Przykładem tego jest Dictionary<TKey, TValue>.TryGetValue, gdy obiekt klucza dostarczony do tej metody zgłasza wyjątek podczas wywoływania GetHashCode. Następnie wynikowy wyjątek to , a nie przechwycony w metodzie TryGetValue - wywołujący zobaczy wyjątek. Ten kod demonstruje to dzieje:

using System; 
using System.Collections.Generic; 

class Foo 
{ 
    public override int GetHashCode() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Program 
{ 
    public static void Main() 
    { 
     Dictionary<object, object> d = new Dictionary<object, object>(); 
     d["bar"] = 42; 

     object s; 
     Foo foo = new Foo(); 
     if (d.TryGetValue(foo, out s)) // results in NotImplementedException 
     { 
      Console.WriteLine("found"); 
     } 
    } 
} 
+0

dziękuję, ale szukam wdrożenia tego wzorca. Jak stworzyć metody takie jak TryParse(). – kofucii

+0

Rzeczywiście, zbyt wielu programistów zakłada, że ​​metody "Try "- * są tylko owijkami do obsługi wyjątków. To zawsze mnie trapi. –

+0

Nigdy nie lubiłem parametrów 'out', ale C# nadal nie daje nam zbyt wiele, aby rozwiązać ten problem w jakikolwiek inny sposób. – andyczerwonka

2

Chyba masz na myśli coś takiego Int32.TryParse lub Dictionary<TKey, TValue>.TryGetValue metody. Ta metoda polega na uniknięciu kosztownego rzucania wyjątków i pozwala wywołującej znać niepowodzenie w inny sposób - w tym przypadku wartość zwracana przez boolowską.

+0

Wiem, do czego służą. Szukam wdrożenia takiego wzoru. Przede wszystkim, co zrobić z podnoszonym wyjątkiem. – kofucii

+0

@kofucii: Nie ma podniesionego wyjątku. Wyjątki nie mają miejsca, niektóre fragmenty kodu muszą je wyrzucać (bardzo niewiele jest uruchamianych w procesorze, ale .NET nadal ma kod do obsługi tego, rzucając wyjątek .NET). Implementacja jest dość prosta, przenieś wartość zwracaną do parametru "out" i zastąp 'throw new WhateverException();' z 'return false;'. –

10

Spodziewałbym się, że implementacja będzie wyglądać bardzo podobnie do wersji "rzucającej" w każdym przypadku - z wyjątkiem sytuacji, w której w wersji do rzucania występuje wyrażenie "throw new FormatException", jest "return false" ... i na koniec ścieżki sukcesu, jest przypisanie do parametru wyjściowego i "return true".

Aby niektóre stopniu można symulować wersję rzucania z non-rzucanie wersji (choć pod względem wydajności nie można zrobić na odwrót) - ty może zadzwoń TryParse a wyjątek jeśli zwróci fałszywy. Oznacza to jednak, że wyjątek nie będzie zawierał szczegółów dotyczących niepowodzenia analizy składni.

Dokładna liczba powtórzeń kodu, które można wykonać - przy zachowaniu dobrej wydajności wersji Try i szczegółowych wyjątków w wersji do rzucania - będzie zależeć od dokładnego zadania.

+0

jasne wyjaśnienie –