?: Koşullu İşleç ile boş değer türü sorunu


154

Birisi bunun neden C # .NET 2.0 çalıştığını açıklayabilir:

    Nullable<DateTime> foo;
    if (true)
        foo = null;
    else
        foo = new DateTime(0);

... ama bu yapmaz:

    Nullable<DateTime> foo;
    foo = true ? null : new DateTime(0);

İkinci form bana derleme hatası veriyor 'Koşullu ifade türü belirlenemiyor çünkü' <null> 've' System.DateTime 'arasında örtük dönüşüm yok. "

Ben eski kullanamazsınız, ama ikinci stil kodumun geri kalanı ile daha tutarlıdır.


12
DateTime kullanarak yazarak çok fazla tasarruf edebilirsiniz? Nullable <DateTime> yerine.
Stewart Johnson

Yanıtlar:


325

Bu soruya birçok kez soru soruldu. Derleyici nasıl dönüştürmek bilmediği anlatıyor nullbir içine DateTime.

Çözüm basit:

DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);

Not Nullable<DateTime>yazılabilir DateTime?size yazarak bir demet kurtaracak.


Yeterince iyi çalışıyor ancak şimdi foo kontrolünü sıfırlayamazsınız - her zaman bir değeri olacaktır. Yine de bunun hiçbir yolu yok - MojoFilter "Üçlü bir operatörde iki değerin aynı tipte olması gerektiğinden" dediği gibi.
DilbertDave

@DilbertDave MojoFilter'ın gönderisindeki bilgiler yanlış.
Mishax

4
Derleyicinin, atanan değişkene bakarak değil, bunun yerine işlenenlere bakarak üçlü işlemin sonuç türünü tahmin etmeye çalıştığını da ekleyeceğim. Ortak ata türünü bulur <null>ve DateTimebulmak yerine, sadece birbirleri arasında bir dönüşüm bulmaya çalışır. (Ekstra bit: C # bir <null>türü, yani her nullifadenin türünü tanır .)
IllidanS4, Monica'nın

Daha önce birkaç kez istendiğinde, yinelenen soru bayrağı nerede?
starmandeluxe

@starmandeluxe muhtemelen hepsi burada işaret (en azından ben buraya nasıl geldiğimi)
Scott Chamberlain

19

FYI (Offtopic, ancak şık ve null olabilecek türlerle ilgili), yalnızca null birleştirme operatörü olarak adlandırılan null edilebilir türler için kullanışlı bir operatörümüz var

??

Bunun gibi kullanılır:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);

9
Bu sorusunu nasıl cevaplıyor?
Stewart Johnson

3
Nick, bazı koşullar doğruysa foo'ya null atamaya çalışıyor. Null birleşme foo null ise DateTime (0) değerini atayacaktır. İkisi tamamen ilgisiz.
Jeromy Irvine

4
Bu yüzden FYI, offtopik ama bilmek güzel bir şey.
FlySwat

Ah tamam. Bilmek oldukça faydalı.
Jeromy Irvine

8

Üçlü bir işleçte, iki değer aynı türe çözümlenmelidir.


10
Hayır, aynı tür olmak zorunda değiller. Ya ikinci işlenenin, üçüncü işlenenin türüne dolaylı olarak dönüştürülebilir olması gerekir.
Mishax

3

Bu sorunun 2008'de sorulduğunu biliyorum ve şimdi 5 yıl sonra ama cevap olarak işaretlenen cevap beni tatmin etmiyor. Gerçek cevap, DateTime'ın bir yapı olduğu ve yapı olarak null ile uyumlu olmadığıdır. Bunu çözmenin iki yolu var:

Birincisi null'u DateTime ile uyumlu hale getirmektir (örneğin 70 upvotes ile beyefendinin önerdiği gibi ObjectTime ya da ValueType'a null atanmış olarak DateTime?

İkincisi, DateTime'ı null ile uyumlu hale getirmektir (örneğin, DateTime'ı DateTime'a mı dökülecek?).


3

Kabul edilene benzer başka bir çözüm de C # 'ın defaultanahtar sözcüğünü kullanmaktır. Jenerikler kullanılarak tanımlanmış olsa da, aslında her tür için geçerlidir.

OP'nin sorusuna uygulanan örnek kullanım:

Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);

Geçerli kabul edilen cevapla örnek kullanım:

DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);

Ayrıca, kullanarak default, nullablebir nulldeğer atamak için değişkeni belirtmeniz gerekmez . Derleyici, belirli değişken türünün varsayılan değerini otomatik olarak atar ve herhangi bir hatayla karşılaşılmaz. Misal:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);

13
Doğru default(DateTime)değil, boş değil, " 1.1.0001 0:00:00", aynı new DateTime(0).
IllidanS4 Monica'nın

@ IllidanS4, bunun eşit olduğunu söylemedim null, sadece kullanarak (MSDN'in belirttiği gibi) default()bir nullabledeğere atayabilirsiniz . Ben göstermek örnekler onunla kullanılabileceğini yönlülük göstermek Nullable<DateTime>, DateTime?ve sadece DateTime. Bunun yanlış olduğuna inanıyorsanız, bunların başarısız olduğu yerlerde bir PoC sağlayabilir misiniz?
newfurniturey

3
Soru soran null, değişkende saklamak istedi , değil default(DateTime), bu en iyi ihtimalle yanıltıcı. Eğer ima olarak bir bütün olarak ifade hala aynı türe sahip, bu durum "çok yönlü" değil - DateTimeve yerini alabilir default(DateTime)ile new DateTime()ve aynı şeyi yapacağız. Belki default(DateTime?)demek istediğin şeydir, çünkü bu aslında eşittir null.
IllidanS4 Monica'nın
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.