กำลังตรวจสอบว่าตัวแปร DateTime มีการกำหนดค่าหรือไม่


132

มีวิธีง่ายๆใน C # เพื่อตรวจสอบว่าอินสแตนซ์ DateTime ได้รับการกำหนดค่าหรือไม่?

คำตอบ:


83

วิธีเดียวในการมีตัวแปรที่ยังไม่ได้กำหนดค่าใน C # คือการเป็นตัวแปรท้องถิ่นซึ่งในกรณีนี้ในเวลาคอมไพล์คุณสามารถบอกได้ว่ามันไม่ได้ถูกกำหนดอย่างแน่นอนโดยพยายามอ่านจากมัน: )

ฉันสงสัยว่าคุณต้องการจริงๆNullable<DateTime>(หรือDateTime?ด้วยน้ำตาลไวยากรณ์ C #) - nullเริ่มต้นด้วยจากนั้นกำหนดDateTimeค่าปกติ(ซึ่งจะถูกแปลงอย่างเหมาะสม) จากนั้นคุณสามารถเปรียบเทียบกับnull(หรือใช้HasValueคุณสมบัติ) เพื่อดูว่ามีการตั้งค่า "จริง" หรือไม่


วิธีการตรวจสอบว่าค่าเท่ากับค่าวันที่และเวลาเริ่มต้นหรือไม่ มีข้อเสียที่มองไม่เห็นของแนวทางนี้หรือไม่? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol

8
@Menol: นั่นไม่ได้บอกความแตกต่างระหว่างเขตข้อมูลที่ได้รับโดยเจตนาdefault(DateTime)และค่าที่เป็นเพียงวิธีเริ่มต้น โดยทั่วไปจะถือว่าค่าหนึ่งภายในโดเมนเป็น "พิเศษและไม่สามารถใช้งานได้ตามปกติ" ซึ่งฉันไม่ชอบ
Jon Skeet

301

คุณหมายถึงอย่างนั้นเหรอ:

DateTime datetime = new DateTime();

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

หรือคุณสามารถใช้ Nullable

DateTime? datetime = null;

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

5
สิ่งที่สองเท่านั้นที่สามารถกันกระสุนได้ ขั้นแรกถือว่าบางอย่างเกี่ยวกับการแสดงวันที่และเวลาที่ไม่ได้ตั้งค่าซึ่งไม่ได้รับการรับรองโดยกรอบงาน โดยส่วนตัวแล้วฉันคิดว่าพวกเขาควรเพิ่มสมาชิก Unset static สำหรับสถานการณ์นี้
Rupert Rawnsley

18
หากต้องการเพิ่มสิ่งที่ @RupertRawnsley กล่าวคุณควรเปรียบเทียบกับค่าเริ่มต้น (DateTime) ซึ่งเป็นค่าของ DateTime ที่ไม่ได้กำหนด มันก็จะเท่ากับ MinValue แต่มันอาจเปลี่ยนแปลงได้
Tsahi Asher

32

วางไว้ที่ใดที่หนึ่ง:

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

แล้ว:

DateTime datetime = ...;

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

ฉันชอบแนวคิดนี้ แต่โปรดทราบว่าในกรณีที่ไม่น่าเป็นไปได้ที่ตัวแปร DateTime ได้รับการกำหนดค่าซึ่งเป็นค่าเริ่มต้นวิธีการขยายนี้จะส่งคืนผลลัพธ์ที่ไม่ถูกต้อง วิธีเดียวที่จะหลีกเลี่ยงปัญหานี้คือการใช้ DateTime ที่เป็นโมฆะซึ่งได้รับการแนะนำไปแล้ว ฉันยังคงชอบ (และตอนนี้กำลังใช้) คำตอบของคุณอยู่ขอบคุณ!
Klicker

@Klicker: ขอบคุณสำหรับความคิดเห็นที่ดี แต่ฉันไม่แน่ใจว่าฉันเข้าใจคำพูดของคุณ เท่าที่ฉันสามารถบอกได้ == ในกรณีนี้จะคืนค่าจริงเสมอเมื่อ datetime เทียบเท่ากับค่าเริ่มต้น (DateTime) อะไรก็ตามที่เป็นวิธีการกำหนดค่าเริ่มต้นวันที่และเวลา ให้ฉันอธิบาย: จริง ๆ แล้วส่วนย่อยที่สองในคำตอบของฉันไม่ถูกต้องมันจะไม่รวบรวมเพราะถ้าคุณคิดว่านี่คือเนื้อความของฟังก์ชั่นวันที่และเวลาจะไม่ถูกกำหนดและคอมไพเลอร์จะปฏิเสธที่จะใช้ ดังนั้นคุณจะต้องกำหนดค่า อาจเป็นค่าเริ่มต้น (DateTime) โดยตรงหรือโดยอ้อม ฉันจะแก้ไขคำตอบของฉัน
sonatique

และถ้าในบริบทอื่นวันที่และเวลาเป็นสมาชิกของคลาสและเหลือไว้ตามที่เป็นอยู่รันไทม์จะกำหนดค่าดีฟอลต์ (DateTime) ให้ == สำหรับโครงสร้างจริงเปรียบเทียบเนื้อหาของโครงสร้างไม่ว่าจะเป็นวิธีที่ส่วนท้ายของโครงสร้างที่เต็มไปด้วยเนื้อหานี้คืออะไร
sonatique

ประเด็นของฉันเกี่ยวข้องกับสมาชิกชั้นเรียนจริงๆเท่านั้นและสิ่งที่ฉันหมายถึงคือ หากคุณมีฟิลด์ DateTime ระดับคลาสหรือคุณสมบัติที่คุณกำหนด MinValue ให้IsEmptyเมธอดของคุณจะคืนค่าจริงซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ (เพราะไม่ว่างเปล่า - ถูกกำหนดค่าเริ่มต้น) IsDefaultValueผมคิดว่าชื่อของวิธีการของคุณจะมากขึ้นตามความเหมาะสม เนื่องจากคุณไม่สามารถจริงๆมี DateTime ไม่ใช่ nullable IsEmptyว่า
Klicker

@ Klicker: ใช่ตกลงเข้าใจแล้ว คุณพูดถูก: ชื่อที่ฉันเลือกทำให้เข้าใจผิด IsDefaultValueคงจะดีขึ้น
sonatique

5

DateTime เป็นชนิดของค่าดังนั้นจึงไม่สามารถเป็นค่าว่างได้ ถ้าคุณคิดว่า DateTime? (Nullable) คุณสามารถใช้:

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

5

ฉันเพิ่งพบว่า GetHashCode () สำหรับวันที่และเวลาที่ไม่ได้กำหนดเป็นศูนย์เสมอ ฉันไม่แน่ใจว่านี่เป็นวิธีที่ดีในการตรวจสอบวันที่และเวลาว่างหรือไม่เพราะฉันไม่พบเอกสารใด ๆ ว่าเหตุใดจึงแสดงพฤติกรรมนี้

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

1
GetHashCodeผลตอบแทน 0 เพราะเห็บ (แทนภายในของ DateTime) นอกจากนี้ยังเท่ากับ 0. unchecked((int)ticks) ^ (int)(ticks >> 32);รหัสแฮคำนวณโดยวิธีการดังต่อไปนี้: โปรดดูที่นี่: referencesource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin

ขอบคุณมาก. ฉันกำลังพยายามทำให้ไฟล์ XML เป็นอนุกรมจากคลาส C # และแยกแอตทริบิวต์ null สิ่งนี้ช่วยได้
Jim Neff


3

new DateTime()ผมว่าค่าเริ่มต้นอยู่เสมอ เราจึงเขียนได้

DateTime datetime;

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

2
โซลูชันนี้มอบให้แล้วโดย + Hath ในปี 2008 และในขณะที่ + Rupert Rawnsley เพิ่มไว้ในความคิดเห็นนั้นไม่สามารถป้องกันกระสุนได้ ...
Roland Bär

0

โดยทั่วไปฉันชอบที่จะใช้ค่าเริ่มต้นของประเภทค่าเพื่อพิจารณาว่าได้ตั้งค่าไว้หรือไม่ เห็นได้ชัดว่าสิ่งนี้ไม่สามารถทำได้ตลอดเวลาโดยเฉพาะอย่างยิ่งกับ ints - แต่สำหรับ DateTimes ฉันคิดว่าการจอง MinValue เพื่อแสดงว่าไม่มีการเปลี่ยนแปลงนั้นยุติธรรมเพียงพอ ข้อดีของสิ่งนี้ในช่วง nullables คือมีสถานที่น้อยกว่าหนึ่งแห่งที่คุณจะได้รับข้อยกเว้นการอ้างอิงที่เป็นโมฆะ (และอาจมีหลายที่ที่คุณไม่ต้องตรวจสอบค่าว่างก่อนเข้าถึง!)


0

หากคุณไม่ต้องการที่จะต้องกังวลกับปัญหาค่า Null เช่นการตรวจสอบค่าว่างทุกครั้งที่คุณใช้มันหรือรวมเข้าด้วยกันในตรรกะบางอย่างและคุณไม่ต้องการที่จะต้องกังวลเกี่ยวกับปัญหาเวลาชดเชยนี่คือ ฉันจะแก้ปัญหาได้อย่างไร:

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

ฉันเพิ่งตรวจสอบว่าค่าเริ่มต้นน้อยกว่าหนึ่งวันหลังจากเวลาเริ่มต้น ใช้งานได้เหมือนมีเสน่ห์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.