2009-09-12 17 views
13

Po lekturze na stackoverflow, że w przypadku sprawdzania formatu DateTime powinieneś użyć DateTime.TryParse. Po wypróbowaniu niektórych wyrażeń regularnych wydają się być długie i nieprzyjemne, aby pokryć wiele formatowania.Null out parametry w C#?

Ale TryParse wymaga parametru "out", a ponieważ chcę tylko sprawdzić format sprawdzania poprawności, nie potrzebuję rzeczywistego wyniku.

Zostaje mi zmienna, która zawiera wynik "out" i nie robię z nim nic. Czy jest jakiś sposób, więc nie muszę robić parametru wyjściowego?

Pozbyłem się tego ostrzeżenia i przestałem mieć zmienną po prostu latającą dookoła.

Odpowiedz

19

Nie. Chciałbym zawinąć go w metodzie gdzieś zachować hałas z głównego strumienia:

bool IsValidDate(string value) 
    { 
    DateTime result; 
    return DateTime.TryParse(value, out result); //result is stored, but you only care about the return value of TryParse() 
    } 
+6

Pomyślę rozszerzając elipsis do rzeczywistych params w swojej odpowiedzi – MPritchard

+0

@Martin - dzięki, tak, uznaje się, że też, ale ponieważ nie wiemy, co format string chobo2 będzie używany, Uznałem, że zna szczegóły lepiej ode mnie. –

+0

Err, spraw, że "dostawca formatu", a nie "ciąg formatu" –

4

No. Nie można pozbyć się zmiennej, ale nie należy się ostrzeżenie kompilatora albo.

Przekazywanie zmiennej jako out "używa" zmiennej. Kompilator nie wyda z tego powodu ostrzeżenia.

+0

twoje prawo Myślałem, że dostaję jeden zgadnij, że był powolny aktualizacji. – chobo2

3

Jeśli korzystasz z platformy .NET 3 i nowszych wersji, możesz zawsze utworzyć metodę rozszerzenia?

public static bool IsValidDate(this string value) 
{ 
    DateTime date = DateTime.Null; 
    return DateTime.TryParse(value, out date); 
} 

[przygotowane do zmienić nazwę metody do bardziej odpowiedni]

+2

Nie trzeba inicjować zmiennej przed przekazaniem jej jako argumentu "out". Wystarczy zadeklarowanie, że to wystarczy. –

+0

Prawda. To tylko nawyk obronny, jaki mam. –

+10

Właściwie w języku C# ten "defensywny" zwyczaj jest w najlepszym razie niepotrzebny, a nawet gorszy, ponieważ sam kompilator wymusi definitywną inicjalizację zmiennej i nie skompiluje się, jeśli zostanie użyty przed jej zainicjowaniem. Jeśli zainicjujesz zmienną, gdy nie jest ona naprawdę potrzebna, a następnie zapomnisz przekazać ją do metody jako argumentu "out", "defensywność" spowoduje, że błąd cichnie zniknie. –

1

TryParse jest lepszym rozwiązaniem. To po prostu zmarnowana zmienna. Inne opcje obejmują użycie Convert.ToDateTime() w bloku try-catch. Ale znowu nie byłoby to skuteczne, ponieważ bloki try-catch mają być ciężkie. Następną opcją jest regex. To lepsze rozwiązanie. Sądzę, że daje to natychmiastowy rezultat w porównaniu do innych.

Można bardzo dobrze owinąć metodę jak Kim Gräsman powiedział ...

+0

Ya na koniec dnia to naprawdę nie jest wielka sprawa, że ​​mam na zmienne latające wokół, ale naprawdę rzeczą, że powinieneś być w stanie użyć null lub coś. Lub powinien mieć tylko parser, który po prostu sprawdza i niczego nie zwraca. – chobo2

7

Nie sugeruję ci faktycznie zrobić to, ale mógłby użyć jednej klasy pomocnika, aby to łatwe dla Wszystkie parametry oUT:

public static class OutHelper<T> 
{ 
    [ThreadStatic] 
    public static T Ignored; 
} 

Następnie można wywołać:

if (DateTime.TryParse(text, out OutHelper<DateTime>.Ignored)) 

To jest okropne, używa publicznego pola zmiennego, a jeśli twoja aplikacja wykonuje również złośliwy kod, daje temu kodowi dostęp do ostatniej wartości, którą sparsowałeś ... ale to powinno zadziałać :)

+0

To sprawia, że ​​moje oczy krwawią. Bezpieczeństwo wątków FAIL. –

+1

@Mebrad: W jaki sposób nie jest bezpieczny dla wątków? Chodzi o to, że nigdy nie czytasz wartości, więc kogo to obchodzi, jeśli jest napisane wiele razy? Mogłoby to * potencjalnie spowodować awarię, gdyby metoda, którą wywołałeś, najpierw napisała do parametru out, a potem ją przeczytała ... ale i tak brzmi to jak zły pomysł. Oczywiście jest to ogólnie ogólnie rzecz biorąc okropny pomysł :) –

+1

@Jon: Chodzi mi o dokładnie sytuację, w której odbiorca używa parametru 'out' jako tymczasowego magazynu, który będzie również zawierał wartość zwracaną po zakończeniu. Chociaż jest to zły pomysł dla osoby, która zakłada, że ​​się nie zmieni, jest to naturalne oczekiwanie. Używanie w tym celu zmiennej globalnej poważnie łamie to założenie. W każdym razie, jak wspomniałeś, jest to w zasadzie "sztuczka" i należy tego unikać w praktyce. –

2

Z C# 7 (od sierpnia 2016 r.) Można użyć konstruktu out, a następnie zignorować nowy var w kolejnym kodzie.

bool success = DateTime.TryParse(value, out var result); 
+0

To powinna być najwyższa głosowana odpowiedź. "wynik" wykracza natychmiast poza zakres zastosowania. – fafrd

+0

To faktycznie zachowa "wynik" dla kodu w tym samym zakresie. W ramach metody można sprawdzić sukces i mieć wartość wyniku (lub domyślną (DateTime)). Również ta notacja nie była obsługiwana przed C# 7 – kskid19