'İnt' ve <null> arasında örtük dönüşüm olmadığından koşullu ifade türü belirlenemiyor


Yanıtlar:


341

Spesifikasyon (§7.14), koşullu ifade için b ? x : y, üç olasılık olduğunu xve yher ikisinin de bir türü olduğunu ve belirli iyi koşulların karşılandığını, sadece bir tanesinin xve ybir türünün olduğunu ve belirli iyi koşulların karşılandığını veya derleme zamanı hatası olduğunu söylüyor. oluşur. Burada, "belirli iyi koşullar", aşağıdaki ayrıntılara gireceğimiz belirli dönüşümlerin mümkün olduğu anlamına gelir.

Şimdi, spesifikasyonun alman kısmına bakalım:

Yalnızca biri xve ytürü varsa ve her ikisi de xve ydolaylı olarak bu türe dönüştürülebilirse, bu koşullu ifadenin türüdür.

Burada mesele şu ki

int? number = true ? 5 : null;

koşullu sonuçlardan yalnızca birinin bir türü vardır. İşte xbir olan intedebi ve yolduğu nullyok ki değil bir türü var ve nullörtük bir dönüştürülebilir değildir int1 . Bu nedenle, "belirli iyi koşullar" karşılanmaz ve derleme zamanı hatası oluşur.

Orada olan bu yaklaşık iki yolu vardır:

int? number = true ? (int?)5 : null;

Burada hala sadece bir tanesinin xve ytipinin olduğu bir durumdayız . Not o null hala bir türü yok henüz derleyici çünkü bu konuda herhangi bir sorun olmayacak (int?)5ve nullher ikisi örtük olarak dönüştürülebilir olan int?(§6.1.4 ve §6.1.5).

Diğer yol ise açıktır:

int? number = true ? 5 : (int?)null;

ama şimdi bunun neden iyi olduğunu anlamak için spesifikasyonda farklı bir madde okumalıyız :

Eğer xtürü olan Xve ytürü vardır Yardından

  • Örtülü bir dönüşüm (§6.1) den varsa Xiçin Ygelen, ancak Yiçin X, daha sonra Ykoşullu ekspresyonu türüdür.

  • Örtülü bir dönüşüm (§6.1) den varsa Yiçin Xgelen, ancak Xiçin Y, daha sonra Xkoşullu ekspresyonu türüdür.

  • Aksi takdirde, hiçbir ifade türü belirlenemez ve bir derleme zamanı hatası oluşur.

İşte xtürü intve ytürü int?. Örtük dönüştürme yoktur int?için int, ancak bir örtük dönüştürme yoktur intiçin int?ifadenin türüdür yüzden int?.

1 : Ayrıca, burada yaygın bir karışıklık kaynağı olan koşullu ifadenin türünü belirlerken sol tarafın türünün göz ardı edildiğine dikkat edin.


4
Bunun neden olduğunu göstermek için spesifikasyondan iyi alıntılar - +1!
JerKimball

8
Başka bir seçenek ise new int?()yerine (int?)null.
Guvante

1
Null olabilecek bir veritabanı alanı türünüz, örneğin null olabilecek bir DateTime öğeniz varsa ve DateTimebunu gerektirdiğinde veri aktarmaya çalıştığınızda da bu durum söz konusudur(DateTime?)
Mike Upjohn

73

null tanımlanabilir bir türü yoktur - mutlu etmek için sadece biraz ürüne ihtiyacı vardır:

int? number = true ? 5 : (int?)null;

3
Veya bunu yapabilirsinizint? number = true ? 5 : null as int?;
Brad M

Güzel cevap noktası çivileme. Güzel ilgili okuma: ericlippert.com/2013/05/30/what-the-meaning-of-is-is
Benjamin

Konudur değil o nulltanımlanabilir bir türüne sahip değil. Sorun, ile arasında örtük dönüşüm nullolmamasıdır int. Ayrıntılar burada .
Jason

ilginç olan şey int? number = true ? 5 : (int?)null;ve int? number = true ? (int?)5 : null;her ikisi de derlemek !! Kazı kazan, çizik
davidhq

2
Ben kapağı tam olarak bu benim olur neden cevap .
jason

4

Diğerlerinin de belirttiği gibi, 5 birdir intve nulldolaylı olarak dönüştürülemez int.

Bu soruna geçici bir çözüm bulmak için başka yollar:

int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();

int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;

int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;

int? num = true ? new int?(5) : null;

Ayrıca, gördüğünüz her yerde int?de kullanabilirsiniz Nullable<int>.


1

Bu C# 9şimdi izin verilen blog

Hedef yazıldı ?? ve ?

Bazen şartlı ?? ve?: ifadelerin dallar arasında açık bir paylaşılan türü yoktur. Bu gibi durumlar bugün başarısız olur, ancak her iki dalın da dönüştüğü bir hedef türü varsa C # 9.0 onlara izin verir:

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

Veya örneğiniz:

// Allowed in C# 9.
int? number = true ? 5 : null;
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.