Bir DateTime değişkeninin atanmış bir değeri olup olmadığını kontrol etme


131

C # içinde bir DateTime örneğine bir değer atanıp atanmadığını kontrol etmenin kolay bir yolu var mı?

Yanıtlar:


83

C # 'da bir değer atanmamış bir değişkene sahip olmanın tek yolu, onun yerel bir değişken olmasıdır - bu durumda, derleme zamanında, ondan okumaya çalışarak onun kesinlikle atanmadığını anlayabilirsiniz: )

Gerçekten istediğinizden şüpheleniyorum Nullable<DateTime>(veya DateTime?C # sözdizimsel şekeri ile) - nullile başlamasını sağlayın ve sonra normal bir DateTimedeğer atayın (uygun şekilde dönüştürülecek). Ardından, "gerçek" bir değerin ayarlanıp ayarlanmadığını görmek nulliçin yalnızca karşılaştırabilirsiniz (veya HasValueözelliği kullanabilirsiniz ).


değerin varsayılan tarih saat değerine eşit olup olmadığını kontrol etmeye ne dersiniz? Bu yaklaşımın fark edilemeyen bir dezavantajı var mı? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol

8
@Menol: Bu, kasıtlı olarak bir değer verilen bir alan default(DateTime)ile başlamak için tam da bu yol olan bir alan arasındaki farkı söylemiyor . Temelde, etki alanı içindeki bir değeri sevmediğim "normal kullanım için özel ve kullanılamaz" olarak ele almaktır.
Jon Skeet

298

öyle mi demek istiyorsun:

DateTime datetime = new DateTime();

if (datetime == DateTime.MinValue)
{
    //unassigned
}

veya Nullable kullanabilirsiniz

DateTime? datetime = null;

 if (!datetime.HasValue)
 {
     //unassigned
 }

5
Bunlardan sadece ikincisi kurşun geçirmezdir. İlki, çerçeve tarafından garanti edilmeyen bir DateTime'ın ayarlanmamış gösterimi hakkında bir şey varsayar. Şahsen ben bu senaryo için bir Unset statik üye eklemeleri gerektiğini düşünüyorum.
Rupert Rawnsley

18
@RupertRawnsley'in söylediği şeyi eklemek için, aslında atanmamış bir DateTime değeri olan varsayılan (DateTime) ile karşılaştırmalısınız. MinValue'ye eşit olur, ancak değişebilir.
Tsahi Asher

32

bunu bir yere koy:

public static class DateTimeUtil //or whatever name
{
    public static bool IsEmpty(this DateTime dateTime)
    {
        return dateTime == default(DateTime);
    }
}

sonra:

DateTime datetime = ...;

if (datetime.IsEmpty())
{
    //unassigned
}

Bu fikri beğendim, ancak pek olası olmayan bir durumda DateTime değişkenine varsayılan değer olan bir değer atandığında, bu uzantı yönteminin yanlış sonucu döndüreceğini unutmayın. Bundan kaçınmanın tek yolu, zaten önerilmiş olan boş değer atanabilir bir DateTime kullanmaktır. Yine de cevabınızı gerçekten seviyorum (ve şimdi kullanıyorum), teşekkürler!
Klicker

@Klicker: Güzel yorumunuz için teşekkür ederim, ama yorumunuzu anladığımdan emin değilim. Bildiğim kadarıyla == bu durumda, datetime varsayılan değere (DateTime) eşdeğer olduğunda her zaman true döndürür. Açıklayayım: aslında cevabımdaki ikinci pasaj yanlıştır, derlenmez, çünkü bunun bir fonksiyonun gövdesi olduğunu düşünüyorsanız, datetime atanmaz ve derleyici onu kullanmayı reddeder. Yani ona bir değer atamanız gerekecek. Doğrudan veya dolaylı olarak varsayılan (DateTime) olabilir. Cevabımı değiştireceğim.
sonatique

ve başka bir bağlamda datetime bir sınıfın üyesiyse ve olduğu gibi bırakılırsa, çalışma zamanı ona varsayılanı (DateTime) atayacaktır. Yapılar için ==, aslında yapının içeriğini karşılaştırır, yapının bu içeriği doldurma şekli ne olursa olsun.
sonatique

Demek istediğim gerçekten sadece sınıf üyeleriyle ilgili ve demek istediğim; MinValue atadığınız sınıf düzeyinde bir DateTime alanınız veya özelliğiniz varsa, IsEmptyyönteminiz true değerini döndürecektir, bu muhtemelen istediğiniz şey değildir (çünkü boş değildir - varsayılan değer atanmıştır). Sanırım yönteminizin adı daha uygun olacaktır IsDefaultValue. Gerçekten boş değer atanamayan bir DateTime'a sahip olamayacağınız için IsEmpty.
Klicker

@Klicker: ah evet, tamam, anladım. Haklısın: seçtiğim isim yanıltıcı. IsDefaultValuedaha iyi olurdu
sonatique

5

DateTime değer türüdür, bu nedenle hiçbir zaman boş olamaz. DateTime düşünüyorsanız? (Nullable) şunları kullanabilirsiniz:

DateTime? something = GetDateTime();
bool isNull = (something == null);
bool isNull2 = !something.HasValue;

5

Atanmamış bir tarih saati için GetHashCode () 'un her zaman sıfır olduğunu öğrendim. Bunun boş tarih saatini kontrol etmenin iyi bir yolu olup olmadığından emin değilim, çünkü bu davranışın neden görüntülendiğine dair herhangi bir belge bulamıyorum.

if(dt.GetHashCode()==0)
{
    Console.WriteLine("DateTime is unassigned"); 
} 

1
GetHashCodeçünkü keneler (DateTime iç gösterimi) geri dönüşü 0 da, aşağıdaki şekilde hesaplanır 0 karma koduna eşit: unchecked((int)ticks) ^ (int)(ticks >> 32);. Ayrıca buraya bakın: referenceource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin

Çok teşekkür ederim. Bir C # sınıfından bir XML dosyasını serileştirmeye ve boş nitelikleri hariç tutmaya çalışıyorum. Bu yardımcı oldu.
Jim Neff


3

Varsayılan değerin her zaman olduğunu söyleyebilirim new DateTime(). Böylece yazabiliriz

DateTime datetime;

if (datetime == new DateTime())
{
    //unassigned
}

2
Bu Çözüm 2008'de + Hath tarafından zaten verilmişti ve + Rupert Rawnsley'in yorum olarak eklediği üzere kurşun geçirmez değildir ...
Roland Bär,

0

Genelde, mümkün olduğunda, ayarlanıp ayarlanmadıklarını belirlemek için değer türlerinin varsayılan değerini kullanmayı tercih ederim. Açıkçası bu her zaman mümkün değil, özellikle de tamsayılar için - ancak DateTimes için MinValue'u değiştirilmediğini belirtmek için ayırmanın yeterince adil olduğunu düşünüyorum. Bunun boş değerlere göre avantajı, boş bir referans istisnası alacağınız bir yerin daha az olmasıdır (ve muhtemelen erişmeden önce boş değeri kontrol etmeniz gerekmeyen çok sayıda yer!)


0

Her kullanışınızda boşluğu kontrol etmek veya bazı mantığa sarmak gibi Boş değer sorunları hakkında endişelenmek istemiyorsanız ve ayrıca ofset zamanı sorunları hakkında endişelenmek istemiyorsanız, o zaman bu sorunu nasıl çözdüm:

startDate = startDate < DateTime.MinValue.AddDays(1) ? keepIt : resetIt

Sadece varsayılan değerin zamanın başlangıcından bir gün sonra olup olmadığını kontrol ediyorum. Tıkır tıkır çalışıyor.

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.