Kiểm tra xem một biến DateTime đã được gán giá trị chưa


131

Có cách nào dễ dàng trong C # để kiểm tra xem liệu đối tượng DateTime có được gán giá trị hay không?

Câu trả lời:


82

Cách duy nhất để có một biến chưa được gán giá trị trong C # là biến đó là biến cục bộ - trong trường hợp đó tại thời điểm biên dịch, bạn có thể nói rằng nó không được gán chắc chắn bằng cách cố gắng đọc từ nó: )

Tôi nghi ngờ bạn thực sự muốn Nullable<DateTime>(hoặc DateTime?với đường cú pháp C #) - làm cho nó nullbắt đầu bằng và sau đó gán một DateTimegiá trị bình thường (sẽ được chuyển đổi một cách thích hợp). Sau đó, bạn có thể chỉ cần so sánh với null(hoặc sử dụng thuộc HasValuetính) để xem liệu giá trị "thực" đã được đặt chưa.


làm thế nào về việc kiểm tra nếu giá trị bằng với giá trị datetime mặc định. Có bất kỳ nhược điểm không thể chú ý đến phương pháp này? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol

8
@Menol: Chà điều đó không nói lên sự khác biệt giữa một lĩnh vực đã cố tình được đưa ra một giá trị default(DateTime)và một lĩnh vực chỉ là cách đó để bắt đầu. Về cơ bản, nó coi một giá trị trong miền là "đặc biệt và không có sẵn cho sử dụng bình thường" mà tôi không thích.
Jon Skeet

298

bạn có nghĩa là như vậy:

DateTime datetime = new DateTime();

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

hoặc bạn có thể sử dụng Nullable

DateTime? datetime = null;

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

5
Chỉ thứ hai trong số này là chống đạn. Cái đầu tiên giả định điều gì đó về biểu diễn unset của DateTime không được đảm bảo bởi khung. Cá nhân tôi nghĩ rằng họ nên đã thêm một thành viên tĩnh Unset cho kịch bản này.
Rupert Rawnsley

18
Để thêm vào những gì @RupertRawnsley đã nói, bạn thực sự nên so sánh với mặc định (DateTime), đó là giá trị của DateTime chưa được gán. Nó chỉ xảy ra tương đương với MinValue, nhưng nó có thể thay đổi.
Tsahi Asher

32

đặt cái này ở đâu đó:

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

sau đó:

DateTime datetime = ...;

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

Tôi thích ý tưởng này, nhưng lưu ý rằng trong trường hợp hơi khó xảy ra là biến DateTime đã được gán một giá trị xảy ra là giá trị mặc định, phương thức tiện ích mở rộng này sẽ trả về kết quả sai. Cách duy nhất để tránh điều này là sử dụng DateTime nullable, đã được đề xuất. Tôi vẫn thực sự thích (và hiện đang sử dụng) câu trả lời của bạn, cảm ơn!
Klicker

@Klicker: Cảm ơn bạn đã nhận xét tốt đẹp của bạn, nhưng tôi không chắc tôi hiểu nhận xét của bạn. Theo như tôi có thể nói == trong trường hợp này sẽ luôn trả về giá trị đúng khi datetime tương đương với mặc định (DateTime) cho dù cách cuối cùng của datetime được gán giá trị mặc định. Hãy để tôi giải thích: thực sự đoạn mã thứ hai trong câu trả lời của tôi là sai, nó sẽ không được biên dịch, bởi vì, nếu bạn cho rằng đây là phần thân của hàm, thì datetime không được gán và trình biên dịch sẽ từ chối sử dụng nó. Vì vậy, bạn sẽ phải gán cho nó một giá trị. Nó có thể được mặc định (DateTime) trực tiếp hoặc gián tiếp. Tôi sẽ sửa đổi câu trả lời của tôi.
sonatique

và nếu trong một bối cảnh khác, datetime là một thành viên của một lớp và nó được giữ nguyên, thì bộ thực thi sẽ gán mặc định (DateTime) cho nó. == cho các cấu trúc thực sự so sánh nội dung của cấu trúc, bất kể đó là cách kết thúc của cấu trúc chứa đầy nội dung này.
sonatique

Quan điểm của tôi chỉ thực sự liên quan đến các thành viên trong lớp, và ý tôi là; nếu bạn có trường hoặc thuộc tính DateTime cấp lớp mà bạn đã gán MinValue cho, IsEmptyphương thức của bạn sẽ trả về đúng, đó có thể không phải là điều bạn muốn (vì nó không trống - nó được gán giá trị mặc định). Tôi đoán tên phương pháp của bạn sẽ phù hợp hơn như IsDefaultValue. Vì bạn thực sự không thể có một DateTime không thể rỗng mà IsEmpty.
Klicker

@Klicker: ah vâng, OK, hiểu rồi. Bạn nói đúng: tên tôi chọn là sai lệch. IsDefaultValuesẽ tốt hơn
sonatique

5

DateTime là loại giá trị, vì vậy nó không bao giờ có thể là null. Nếu bạn nghĩ DateTime? (Không thể) bạn có thể sử dụng:

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

5

Tôi vừa phát hiện ra rằng GetHashCode () cho một datetime chưa được gán luôn luôn bằng không. Tôi không chắc đây có phải là một cách tốt để kiểm tra null datetime không, bởi vì, tôi không thể tìm thấy bất kỳ tài liệu nào về lý do tại sao hành vi này được hiển thị.

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

1
GetHashCodetrả về 0 vì dấu tích (biểu diễn bên trong của DateTime) cũng bằng 0. Mã băm được tính theo cách sau : unchecked((int)ticks) ^ (int)(ticks >> 32);. Xem thêm ở đây: referencesource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin

Cảm ơn rât nhiều. Tôi đang cố gắng tuần tự hóa một tệp XML từ một lớp C # và loại trừ các thuộc tính null. Điều này đã giúp.
Jim Neff


3

Tôi muốn nói giá trị mặc định là luôn luôn new DateTime(). Vì vậy chúng tôi có thể viết

DateTime datetime;

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

2
Giải pháp này đã được + Hath đưa ra vào năm 2008 và, khi + Rupert Rawnsley thêm vào dưới dạng nhận xét, không phải là chống đạn ...
Roland Bär

0

Tôi thường thích, nếu có thể, sử dụng giá trị mặc định của các loại giá trị để xác định xem chúng đã được đặt chưa. Điều này rõ ràng là không thể mọi lúc, đặc biệt là với các số nguyên - nhưng đối với DateTimes, tôi nghĩ rằng việc đặt MinValue để biểu thị rằng nó đã không được thay đổi là đủ công bằng. Lợi ích của việc này là vô giá trị là có một nơi ít hơn nơi bạn sẽ có ngoại lệ tham chiếu null (và có thể rất nhiều nơi bạn không phải kiểm tra null trước khi truy cập!)


0

Nếu bạn không muốn phải lo lắng về các vấn đề giá trị Null như kiểm tra null mỗi khi bạn sử dụng hoặc gói nó trong một số logic và bạn cũng không muốn phải lo lắng về vấn đề thời gian bù, thì đây là Làm thế nào tôi giải quyết vấn đề:

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

Tôi chỉ kiểm tra xem giá trị mặc định là ít hơn một ngày sau khi bắt đầu thời gian. Hoạt động như một lá bùa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.