DateTime. TryParse'ı Nullable <DateTime> ile nasıl kullanırım?


115

Bir dizenin datetime değerini Nullable'a almak için DateTime. TryParse yöntemini kullanmak istiyorum. Ama bunu denediğimde:

DateTime? d;
bool success = DateTime.TryParse("some date text", out (DateTime)d);

derleyici bana söyler

'out' bağımsız değişkeni bir değişken olarak sınıflandırılmaz

Burada ne yapmam gerektiğinden emin değilim. Ben de denedim:

out (DateTime)d.Value 

ve bu da çalışmıyor. Herhangi bir fikir?

Yanıtlar:


123
DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;

(Daha zarif çözümler olabilir, ancak neden yukarıdaki gibi bir şey yapmıyorsunuz?)


3
Haklısın, halletmek için daha çok tek hatlı bir adam arıyordum, ama sanırım bu işe yarar. Bu temp değişkenini yaratmayı sevmiyorum, dağınık hissettiriyor. : - / Görünüşe göre bu senaryo daha iyi desteklenmeli.
Brian Sullivan

1
Binary Worrier'in bunu bir uzantı yöntemine psuedo-inline önerisine bakın.
David Alpert

4
Neden DateTime'ı DateTime'a yayınlıyorsunuz? TryParse'a geçirmeden önce d2'yi geri almanıza gerek yoktur.
Aaron Powell

@Slace - Önerinizi eklemek için yanıtı güncelledim.
Drew Noakes

@Jason Kealey Umarım bu VS2012'de zaten tanıtılmıştır, aksi takdirde bu iyi kod parçasını kullanmaya devam etmem gerekecek.
Pimenta

161

Jason'ın dediği gibi, doğru türde bir değişken oluşturabilir ve bunu iletebilirsiniz. Kendi yönteminizle özetlemek isteyebilirsiniz:

public static DateTime? TryParse(string text)
{
    DateTime date;
    if (DateTime.TryParse(text, out date))
    {
        return date;
    }
    else
    {
        return null;
    }
}

... veya koşullu işleci seviyorsanız:

public static DateTime? TryParse(string text)
{
    DateTime date;
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null;
}

Veya C # 7'de:

public static DateTime? TryParse(string text) =>
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null;

5
Muhtemelen The Skeet ile tartışmamalıyım, ama ... TryParse adında bir yöntemin TryParse kuralını izleyip bir boolean döndürmesini beklediğim için yönteminizi Parse çağırmalısınız. ;-)
Myster

@ Myster: Her iki durumda da tam olarak mevcut konvansiyonu takip etmiyor - eskiden sadece Parsegeri dönmesini DateTimeve başarısızlık durumunda bir istisna atmasını bekler , değil mi? Ama evet, ne istersen yapabilirsin ... ve Noda Time'da Parsebunun yerine ilgili yöntemleri adlandırdım .
Jon Skeet

1
elseAnahtar kelimelerinin son nokta bu yana (ilk örnekte) gereksizdir ifbloğun ulaşılabilir olamaz.
Jeppe Stig Nielsen

1
@JeppeStigNielsen: Evet, gereksiz - ancak simetri için biçimsel olarak tercih edilebilir. Bu sadece kişisel bir tercih (ve ben de tutarlı değilim ...)
Jon Skeet

3
@Kiquenet: else kullanılması, yollardan birinin veya diğerinin alınacağını ve her ikisinin de geri döneceğini daha net hale getirir. Büyük ölçüde iç içe geçmiş koda karşıyım, ancak bu durumda bu gerçekten bir IMO sorunu değil.
Jon Skeet

20

İşte Jason'ın önerdiği şeyin biraz kısaltılmış bir baskısı:

DateTime? d; DateTime dt;
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null;

18

Yapamazsınız çünkü Nullable<DateTime>farklı bir türdür DateTime. Bunu yapmak için kendi fonksiyonunuzu yazmanız gerekiyor,

public bool TryParse(string text, out Nullable<DateTime> nDate)
{
    DateTime date;
    bool isParsed = DateTime.TryParse(text, out date);
    if (isParsed)
        nDate = new Nullable<DateTime>(date);
    else
        nDate = new Nullable<DateTime>();
    return isParsed;
}

Bu yardımcı olur umarım :)

DÜZENLEME: Yanlış test edilmiş uzantı yöntemi kaldırıldı, çünkü "bu" parametresini değiştirmeye çalışan uzantı yöntemleri (bazı kötü hoor tarafından belirtildiği gibi) Değer Türleri ile çalışmayacaktır.

Not: Söz konusu The Bad Hoor eski bir dost :)


Tarihi başlatmak istemezsiniz [bunu bir dış param olarak kullandığınız için] Tamam, seçici olmayı bırakacağım!
Ruben Bartelink

Bende derleyici yok, ancak DateTime bir değer türü olduğundan, uzantı yöntemi def derleme yapıyor mu?
Ruben Bartelink

Siz belirleyene kadar sonuç geri gelmez - [TestFixture] public class WhenExtending {[Test] public void TryParseShouldWork () {DateTime? x = boş; var res = Externders. TryParse (x, "1/1/1990"); Assert.IsTrue (res)
Ruben Bartelink

; Assert.That (x! = Null); }} Assert'te başarısız oluyor, yani, DateTime bir değer türü olduğu için sonuç değiştirilmiyor (ki bu telefon ekranlarında her zaman güzel bir ayıklama sorusudur: D)
Ruben Bartelink

(obv ilk (uzantı olmayan) işe yarayacaktır, ancak dışarıda olmalıdır, ref değil - ve genel olarak TryXXX API'lerine uymazsa sonucu geçersiz kılmalısınız - FDG'nin bundan bahsettiğinden oldukça eminim. Seçici!
Ruben Bartelink

4

Bir uzatma yöntemi oluşturmaya ne dersiniz?

public static class NullableExtensions
{
    public static bool TryParse(this DateTime? dateTime, string dateString, out DateTime? result)
    {
        DateTime tempDate;
        if(! DateTime.TryParse(dateString,out tempDate))
        {
            result = null;
            return false;
        }

        result = tempDate;
        return true;

    }
}

2
Bu ilk parametre ne dateTimeiçin? Asla kullanılmaz.
Mike Zboray

1
@mikez - uzantı yöntemleri böyle çalışır, derleyici tarafından bir uzantı yöntemi olması gerektiğini bilmek için kullanılır.
Erik Funkenbusch

3
@MystereMan Bir uzatma yönteminin ne olduğunu biliyorum. Bir uzatma yöntemi için daha uygun bir imza olacaktır DateTime? TryParse(this string dateString). Bu uygulama çok tuhaf.
Mike Zboray

3
@mikez - o zaman neden ne için olduğunu sordun? Yalnızca tarih saatine ihtiyacınız varken dize ad alanını neden kirletesiniz? Amaç, DateTime. TryParse'a bir analog sağlamaktır, yani DateTime? TryParse
Erik Funkenbusch

1
Bu uzantı yöntemi @ErikFunkenbusch değil gibi bir çağrı sözdizimi izin (DateTime?).TryParse( ... )veya Nullable<DateTime>.TryParse( ... ). Yani Mike Z haklı, bu yöntem için aptalca bir imza.
Jeppe Stig Nielsen

1

Microsoft'un bunu neden halletmediğini anlamıyorum. Bununla başa çıkmak için akıllı küçük bir yardımcı program yöntemi (sorunu int ile yaşadım, ancak int'i DateTime ile değiştirmek aynı etkiyi yaratabilir, .....

    public static bool NullableValueTryParse(string text, out int? nInt)
    {
        int value;
        if (int.TryParse(text, out value))
        {
            nInt = value;
            return true;
        }
        else
        {
            nInt = null;
            return false;
        }
    }

1

Bu aradığınız tek satırlık:

DateTime? d = DateTime.TryParse("some date text", out DateTime dt) ? dt : null;

Bunu uygun bir TryParse sözde genişletme yöntemi yapmak istiyorsanız, bunu yapabilirsiniz:

public static bool TryParse(string text, out DateTime? dt)
{
    if (DateTime.TryParse(text, out DateTime date))
    {
        dt = date;
        return true;
    }
    else
    {
        dt = null;
        return false;
    }
}

@robnick Söylediklerimden farkı ne?
cpcolella

1
Önceki yorumumu yoksayın (çözümünüze oy verdim!), En son C # için null: DateTime? d = DateTime. TryParse (falan, DateTime dt dışında)? dt: (DateTime?) null;
robnick

1

İşte tek satırlık bir çözüm:

DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;

-3

Alternatif olarak, ortaya çıkan olası istisna ile ilgilenmiyorsanız, TryParse for Parse'ı değiştirebilirsiniz:

DateTime? d = DateTime.Parse("some valid text");

Başarıyı gösteren bir boole de olmayacak olsa da, giriş metninin her zaman geçerli olacağını bildiğiniz bazı durumlarda pratik olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.