Tampaknya Nullable<int>dan int?nilainya setara. Apakah ada alasan untuk memilih salah satu dari yang lain?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Tampaknya Nullable<int>dan int?nilainya setara. Apakah ada alasan untuk memilih salah satu dari yang lain?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Jawaban:
Tidak ada perbedaan.
int?hanyalah singkatan dari Nullable<int>, yang dengan sendirinya merupakan singkatan dari Nullable<Int32>.
Kode yang dikompilasi akan persis sama dengan yang Anda pilih untuk digunakan.
The ?bentuk hanya singkatan untuk jenis penuh. Preferensi pribadi adalah satu-satunya alasan untuk memilih satu di antara yang lain.
Detail lengkapnya di sini .
Sintaksnya
T?adalah singkatan dariNullable<T>, di manaTadalah tipe nilai. Kedua bentuk tersebut dapat dipertukarkan.
Sementara saya sepenuhnya setuju bahwa dalam kebanyakan kasus mereka adalah sama, saya baru-baru datang di sebuah situasi, ketika ada adalah perbedaan antara kedua. Untuk detail yang mengerikan lihat pertanyaan ini , tetapi untuk memberi Anda contoh singkat di sini:
void Test<T>(T a, bool b)
{
var test = a is int? & b; // does not compile
var test2 = a is Nullable<int> & b; // does compile
}
Baris pertama memberikan pesan kesalahan berikut:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
Jika Anda penasaran dengan alasan pasti untuk ini, saya sangat menyarankan Anda untuk memeriksa pertanyaan yang sudah ditautkan , tetapi masalah dasarnya adalah bahwa dalam fase penguraian setelah operator is(atau as), ketika kita menghadapi ?token, kita memeriksa apakah yang berikutnya token dapat diartikan sebagai operator unary ( &bisa jadi satu) dan jika demikian: parser tidak peduli tentang kemungkinan ?token menjadi pengubah tipe, ia hanya menggunakan tipe sebelumnya, dan akan mengurai sisanya seolah-olah ?token adalah operator terner (sehingga penguraian akan gagal).
Jadi, meskipun secara umum int?dan Nullable<int>dapat dipertukarkan, ada beberapa kasus sudut ketika menghasilkan hasil yang sangat berbeda, karena cara parser melihat kode Anda.
testdiperbaiki dengan tanda kurung, jadi var test = (a is int?) & b;. Bisa juga diperbaiki dengan var test = a is int? && b;, dan mengingat bahwa badalah parameter nilai sederhana (tidak ada efek samping pada evaluasi) tampaknya aneh untuk memilih &lebih &&.
?adalah karakter kunci.
int?sebagai operasi terner ( var test = a is int? <return if true> : <return if false>), bukan int nullable.
boolkelebihan beban tertentu ini . Ini adalah operator logika Boolean ( &untuk bool) dan operator logika bersyarat Boolean ( &&untuk bool). Perhatikan bagaimana subbagian pertama ini dengan jelas dinamai logis . Ingat, di C # tidak ada konversi ("cast") antara booldan tipe numerik!
Tampaknya ada perbedaan antara keduanya saat menggunakan pembuatan Code-first Entity Framework (EF):
Ketika entitas Anda berisi properti yang dinyatakan seperti:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF tidak akan menghasilkan properti nullable dan Anda harus memaksa generator untuk menjadikannya nullable seperti:
public class YourContext : DbContext
{
public DbSet<MyEntity> MyEntities{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional();
}
}
Di sisi lain, jika Anda mendeklarasikan entitas Anda seperti:
public class MyEntity
{
public int? MyNullableInt { get; set; }
}
generator EF akan menghasilkan properti nullable dengan kolom nullable di tabel database terkait.
Nullabledefinisi lain di suatu tempat, karena dengan built-in Nullable<T>, EF tidak mungkin melihat perbedaan antara keduanya. Bahkan jika orang-orang EF ingin memperlakukan mereka secara berbeda, mereka tidak bisa.
Nullable adalah tipe generik, tapi int? tidak.
Ada beberapa skenario di mana Nullable harus digunakan melalui int?
misalnya: di sini Anda tidak dapat mengganti Nullable dengan int?
bagaimana Anda bisa mengubah kode di bawah ini tanpa menggunakan Nullable ?
class LazyValue<T> where T : struct
{
private Nullable<T> val;
private Func<T> getValue;
// Constructor.
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
// Execute the delegate.
val = getValue();
return (T)val;
}
}
}
Nullable<T>ituNullable<int>