2009-11-06 15 views
48

UPDATECzy istnieje GUID.TryParse() w .NET 3.5?

Guid.TryParse jest dostępne w .NET 4.0

End Aktualizuj

Oczywiście nie ma GUID.TryParse publicznego() w .NET CLR 2.0.

Tak więc, szukałem wyrażeń regularnych [a także szukałem go w wyszukiwarce] i za każdym razem, gdy znalazłem jeden, był gorący argument w sekcji komentarzy o RegEx A nie działa, użyj RegEx B. Wtedy ktoś by napisz Regex C yadda yadda

Tak czy inaczej, Postanowiłem zrobić to, ale źle się z tym czuję.

public static bool IsGuid (string possibleGuid) { 

    try { 
     Guid gid = new Guid(possibleGuid); 
     return true;  
    } catch (Exception ex) { 
     return false; 
    } 
} 

Oczywiście ja nie lubię tego, ponieważ został wywiercony we mnie od samego początku, aby uniknąć rzucania wyjątków, jeśli możesz defensibly kod wokół niego.

Czy ktoś wie, dlaczego nie ma publicznego Guid.TryParse() w systemie .NET Framework?

Czy ktoś ma prawdziwe wyrazy regularne, które będą działać dla wszystkich identyfikatorów GUID?

+3

Technika próbnego połowu może być zła, jeśli ta metoda jest wywoływana jako partie (w ciasnej pętli), a prawdopodobieństwo wyrzucenia wyjątku jest wysokie. Kiedyś profilowałem aplikację ASP.NET 1.1, która to zrobiła i po uaktualnieniu jej do int.TryParse .NET 2.0, wydajność wzrosła o około 30% (robił dużo połączeń int.Parse!). – RichardOD

+0

Tak, to nie będzie pętla. Zasadniczo otrzymuję błędy "nieudanej konwersji do uniqueidentifier" itp., Więc chciałem zrobić coś więcej niż tylko sprawdzić, czy przekazywany ciąg znaków był pusty, czy nie. –

+0

string Id = Guid.NewGuid(). ToString(); –

Odpowiedz

55

Brak pliku Guid.TryParse w CLR 2.0 i wcześniejszych wersjach. Będzie dostępny od wersji CLR 4.0 i Visual Studio 2010.

Dlaczego nie było. Tego rodzaju pytania zwykle trudno jest odpowiedzieć poprawnie. Najprawdopodobniej był to problem związany z niedopatrzeniem lub ograniczeniem czasowym. Jeśli otworzysz mscorlib w reflektorze, zobaczysz, że faktycznie jest to metoda o nazwie TryParse na Guid, ale jest prywatna. W niektórych przypadkach zgłasza również wyjątek, więc nie jest dobrym odpowiednikiem, powiedzmy, Int32.TryParse.

+4

+1 tylko dlatego, że jest to interesująca odpowiedź. Zauważyłem, że TryParse jest wywoływana przez konstruktora. – RichardOD

+1

Bardzo interesujące. Patrząc na implementację konstruktora Guid (string) w reflektorze, kręciło mi się w głowie. Zastanawiam się, jak ludzie z Redmond utrzymują ten kod :-) –

+0

Tak, dlatego wspomniałem "dlaczego nie było publicznej TryParse()" Dzięki jared –

5

Pod względem tego, dlaczego go nie ma, jest to niedopatrzenie. W usłudze .NET 4 pojawi się numer Guid.TryParse (szczegóły: BCL blog post).

19

Guid.TryParse implementacja za pomocą wyrażeń regularnych.

+0

Nice. Prawdopodobnie dodaję tam również opcję catch catch, ale na pewno (przynajmniej dopóki nie będę pewny, że niczego nie przeoczyłem w Regeksie). – RichardOD

+0

Zaimplementowałeś to? –

+1

Nie, do tej pory w moim nosniku programistycznym nigdy nie potrzebowałem takiej funkcjonalności. –

0

W tej chwili nie ma funkcji TryParse w .NET Framework. Będziesz musiał uciekać się do RegEx lub opcji try-catch. RegEx nie jest moją filiżanką herbaty, więc jestem pewien, że ktoś inny opublikuje odpowiedź.

Wyjątki są drogie pod względem wydajności, więc mój głos przechodzi do opcji RegEx.

0

To powinno działać:

@"^\{?[0-9a-fA-F]{8}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{12}\}?$" 
+0

Oznacza to, że "{00000000-0000-0000-0000-000000000000" jest legalnym identyfikatorem GUID. Czy naprawdę * chcesz pozwolić na niedopasowane szelki? I dlaczego łączniki są opcjonalne? –

+1

To miał być "szybki i brudny" sposób na dopasowanie ciągów GUID. Wykonanie odpowiedniego dopasowania klamrowego i łącznika byłoby bardzo skomplikowane w regexie (tak naprawdę byłoby to kilka wyrażeń). Zgodnie z dokumentami dla 'Guid (string)' łączniki są opcjonalne. – jheddings

0

Możesz napisać własną TryParse jako metodę rozszerzenia dla GUID. Wtedy, gdy pojawi się "prawdziwy" z MS, twój już dobry, aby przejść i nie trzeba się zmieniać.

+1

Poza tym metoda rozszerzenia dotyczy tylko instancji 'Guid', a wersja szkieletowa będzie statyczna. – LukeH

+0

Ah tak, dag nabbit – ryber

10

IsGuid realizowane jako metodę rozszerzenia na ciąg ...

public static bool IsGuid(this string stringValue) 
{ 
    string guidPattern = @"[a-fA-F0-9]{8}(\-[a-fA-F0-9]{4}){3}\-[a-fA-F0-9]{12}"; 
    if(string.IsNullOrEmpty(stringValue)) 
    return false; 
    Regex guidRegEx = new Regex(guidPattern); 
    return guidRegEx.IsMatch(stringValue); 
} 
+4

Zachowanie jest zamierzone, łańcuch pusty nie jest prawidłowym przewodnikiem i dlatego zwraca wartość false. –

+1

Dlaczego wywołanie metody null zawsze spowoduje odrzucenie wyjątku odwołania zerowego? Nienawidzę wyjątków referencyjnych o wartości zerowej. Lubię metody rozszerzeń z tego konkretnego powodu. Utrzymuje mój kod z dala od sprawdzeń zerowych. – jeromeyers

+0

Implementacja jest niepoprawna. Poprawne jest 'string guidPattern = @"^[a-fA-F0-9] {8} (\ - [a-fA-F0-9] {4}) {3} \ - [a-fA-F0- 9] {12} $ ";' –

7

Ta implementacja TryParse identyfikatorów GUID używa try-catch aby złapać missformed GUID.Jest on realizowany jako metodę rozszerzenia und muszą być umieszczone w klasie statycznej:

public static bool TryParseGuid(this string s, out Guid guid) 
{ 
    try { 
     guid = new Guid(s); 
     return true; 
    } catch { 
     guid = Guid.Empty; 
     return false; 
    } 
} 

to można nazwać z

string s = "{CA761232-ED42-11CE-BACD-00AA0057B223}"; 
Guid id; 
if (s.TryParseGuid(out id) { 
    // TODO: use id 
} else { 
    // Sorry not a valid Guid. 
} 

Począwszy od C# 7.0/Visual Studio 2017, można to nazwać z:

string s = "{CA761232-ED42-11CE-BACD-00AA0057B223}"; 
if (s.TryParseGuid(out Guid id) { 
    // TODO: use id 
} else { 
    // Sorry not a valid Guid. 
} 

UPDATE

Od Visual Studio 2010/.NET Framework 4.0, System.Guid zapewnia TryParse oraz sposobu TryPareExact.

Powiązane problemy