Görünüşe göre Nullable<int>ve int?değer olarak eşdeğer. Birini diğerine tercih etmek için herhangi bir sebep var mı?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Görünüşe göre Nullable<int>ve int?değer olarak eşdeğer. Birini diğerine tercih etmek için herhangi bir sebep var mı?
Nullable<int> a = null;
int? b = null;
a == b; // this is true
Yanıtlar:
?Form tam türü için sadece bir kısaltmadır. Kişisel tercih, birini diğerine tercih etmenin tek nedenidir.
Tüm ayrıntılar burada .
Sözdizimi
T?, değer türüNullable<T>neredeTolduğu için kısaltmadır . İki form birbirinin yerine kullanılabilir.
Tamamen çoğu durumda aynı olduğunu kabul ederken orada, ben son zamanlarda bir durum rastladım olan bu ikisinin arasında bir fark. Kanlı ayrıntılar için bu soruya bakın , ancak size hızlı bir örnek vermek için burada:
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
}
İlk satır aşağıdaki hata mesajlarını verir:
error CS1003: Syntax error, ':' expected
error CS1525: Invalid expression term ';'
Bunun tam nedenini merak ediyorsanız, zaten bağlantılı soruyu kontrol etmenizi gerçekten tavsiye ederim , ancak temel sorun şu ki, bir is(veya bir as) operatörden sonra ayrıştırma aşamasında , bir ?jetonla karşılaştığımızda bir sonraki olup olmadığını kontrol ediyoruz. belirteç olabilir tekli operatör olarak yorumlanabilir ( &biri olabilir) ve eğer öyleyse: ayrıştırıcı olasılığı umursamayan ?belirteç bir tür değiştirici varlık, sadece kendinden önceki türünü kullanır ve dinlenme ayrıştırmak olacak sanki ?belirteç üçlü bir işleçti (bu nedenle ayrıştırma başarısız olacaktır).
Dolayısıyla, genel olarak int?ve Nullable<int>birbirinin yerine geçebilirken, ayrıştırıcının kodunuzu nasıl gördüğünden dolayı tamamen farklı sonuçlar ürettikleri bazı köşe durumları vardır.
testbir parantez ile sabitlenmiştir, bu yüzden var test = (a is int?) & b;. Ayrıca sabitlenebilir var test = a is int? && b;ve bbunun basit bir değer parametresi olduğu göz önüne alındığında (değerlendirmede yan etkisi yoktur), tercih &edilmesi garip görünmektedir &&.
?anahtar bir karakterdir.
int?üçlü bir işlem ( var test = a is int? <return if true> : <return if false>) olarak yorumlandığı için derlenmiyor.
boolaşırı yüklenmeler için belgelere bakın . Bunlar Boolean mantıksal operatörler ( &for bool) ve Boolean koşullu mantıksal operatörlerdir ( &&for bool). Bu alt bölümlerden ilkinin nasıl açıkça mantıksal olarak adlandırıldığına dikkat edin . Unutmayın, C # 'da boolve sayısal türler arasında dönüştürme ("yayınlama") yoktur !
Görünüşe göre, kod ilk Entity Framework (EF) üretimi kullanılırken ikisi arasında bir fark var:
Varlığınız aşağıdaki gibi beyan edilen bir özellik içerdiğinde:
public class MyEntity
{
public Nullable<int> MyNullableInt { get; set; }
}
EF, null yapılabilir bir özellik oluşturmaz ve oluşturucuyu şu şekilde null yapılabilir hale getirmeye zorlamanız gerekir:
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();
}
}
Öte yandan, varlığınızı şöyle beyan ederseniz:
public class MyEntity
{
public int? MyNullableInt { get; set; }
}
EF oluşturucu özelliği, ilgili veritabanı tablosunda null yapılabilir bir alanla null yapılabilir bir özellik oluşturur.
Nullableyerde başka bir tanımınız olduğunu gösterir, çünkü yerleşik ile, Nullable<T>EF'nin ikisi arasındaki farkı görmesi mümkün değildir. EF çalışanları onlara farklı davranmak isteseler bile yapamazlardı.
Nullable genel bir türdür, ancak int?değil.
Nullable'ın üzerinde kullanılması gereken bazı senaryolar vardır . int ?
örneğin: burada Nullable'ı int ile değiştiremezsiniz ?
Nullable kullanmadan aşağıdaki kodu nasıl değiştirebilirsin ?
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>o enNullable<int>