Bu kod satırı boyunca koştu:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
İki soru işareti ne anlama geliyor, bir tür üçlü operatör mü? Google'a bakmak zor.
Bu kod satırı boyunca koştu:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
İki soru işareti ne anlama geliyor, bir tür üçlü operatör mü? Google'a bakmak zor.
Yanıtlar:
Bu boş birleştirme operatörü ve üçlü (hemen-if) operatörü gibi. Ayrıca bakınız ?? Operatör - MSDN .
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
genişler:
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
daha da genişler:
if(formsAuth != null)
FormsAuth = formsAuth;
else
FormsAuth = new FormsAuthenticationWrapper();
İngilizce'de, "Soldaki her şey boş değilse, bunu kullanın, aksi takdirde sağdaki olanı kullanın."
Bunların herhangi bir sayısını sırayla kullanabileceğinizi unutmayın. Aşağıdaki deyim olmayan ilk null adlı atar Answer#
için Answer
(bütün Cevapları boş ise o zaman Answer
null):
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
Ayrıca, yukarıdaki genişleme kavramsal olarak eşdeğerken, her bir ifadenin sonucu sadece bir kez değerlendirilir. Örneğin, bir ifade yan etkileri olan bir yöntem çağrısı ise bu önemlidir. (Bunu işaret ettiği için @Joey'e teşekkür ederiz.)
??
çağrışımsaldır, yani a ?? b ?? c ?? d
eşdeğerdir ((a ?? b) ?? c ) ?? d
. "Atama işleçleri ve üçlü işleç (? :) sağ ilişkiseldir. Diğer tüm ikili işleçler ilişkisel kalır." Kaynak: msdn.microsoft.com/en-us/library/ms173145.aspx
Başka hiç kimse sihirli kelimeleri henüz söylemediğinden: boş birleştirme operatörü . C # 3.0 dil spesifikasyonunun 7.12 bölümünde tanımlanmıştır .
Özellikle bir ifadede birden çok kez kullanıldığında çalışma şekli nedeniyle çok kullanışlıdır. Formun bir ifadesi:
a ?? b ?? c ?? d
a
null değilse ifadenin sonucunu verecektir , aksi takdirde deneyin b
, aksi takdirde deneyin c
, aksi takdirde deneyin d
. Her noktada kısa devre yapar.
Ayrıca, türünün d
null değeri yoksa, tüm ifadenin türü de null değeri yoktur.
Boş birleştirme operatörü.
http://msdn.microsoft.com/en-us/library/ms173224.aspx
Evet, ne dediğini bilmiyorsanız aramak neredeyse imkansız! :-)
EDIT: Ve bu başka bir sorudan harika bir özellik. Onları zincirleyebilirsiniz.
Herkese teşekkürler, burada MSDN sitesinde bulduğum en kısa açıklama:
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
-1
sadece düz int
olmayan null).
x
tiptedir int?
, ancak y
tiptedir int
, yazabilirsiniz int y = (int)(x ?? -1)
. Bu ayrıştırmak olacak x
bir etmek int
Değilse null
veya atamak -1
için y
eğer x
olduğunu null
.
İki soru işareti (??) bir Coalescing operatörü olduğunu gösterir.
Birleştirme operatörü bir zincirden ilk NON-NULL değerini döndürür. Her şeyi pratik olarak gösteren bu youtube videosunu görebilirsiniz .
Ama videonun söylediklerine daha fazlasını ekleyeyim.
İngilizcenin birleşmesinin anlamını görürseniz “birlikte konsolide” yazıyor. Örneğin, dört dizeyi zincirleyen basit bir birleştirme kodu.
Yani eğer str1
olduğunu null
o çalışacağız str2
eğer str2
olduğunu null
o çalışacağız str3
ve bu yüzden boş olmayan bir değere sahip bir dize bulana kadar üzerinde.
string final = str1 ?? str2 ?? str3 ?? str4;
Basit bir deyişle, Birleştirme operatörü bir zincirden ilk NON-NULL değerini döndürür.
Üçlü operatör için kısa el.
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
Veya üçlü yapmayanlar için:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
!= null
) hem de ikincisi formsAuth
(sonra ?
) değiştirilebilir; null birleştirme formunda, her ikisi de sağladığınız değerleri örtük olarak alır.
Ruby'ye aşina iseniz, ||=
C # 'a benzer ??
. İşte biraz Ruby:
irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"
Ve C # ile:
string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";
x ||= y
desugarlar gibi bir şeye x = x || y
, yani Ruby'deki ??
ovaya daha benzer ||
.
??
sadece umurunda hakkında null
, oysa ||
çoğu dilde olduğu gibi Ruby operatör, fazlasıdır null
, false
bir değere sahip bir boolean kabul edilebilir, ya da bir şey false
(bazı dillerde örneğin ""
). Bu iyi ya da kötü bir şey değil, sadece bir fark.
Bu konuda tehlikeli bir şey yok. Aslında çok güzel. İstenirse varsayılan değer ekleyebilirsiniz, örneğin:
KOD
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
int? x1 = null;
Doğru mu
x1
- x4
null türleri OLMALIDIR: etkin, "sonucudur söylemek anlamsızdır 0
eğer x4
(muhtemelen alamaz bir değerdir" null
). Burada "boş değer türü", hem boş değer değer türlerini hem de referans türlerini içerir. Zincirleme değişkenlerden biri veya daha fazlası (sonuncusu hariç) geçersiz kılınamazsa, derleme zamanı hatasıdır.
Çok sayıda cevaba doğru bir şekilde işaret ettiği gibi, "boş birleştirme operatörü" ( ?? ), bunun da kuzenini kontrol etmek isteyebileceğiniz "Boş Koşullu Operatör" ( ?. Veya ? [ ) birçok kez ??
Üye erişimi ( ?. ) Veya dizin ( ? [ ) İşlemini gerçekleştirmeden önce null değerini sınamak için kullanılır . Bu işleçler, özellikle veri yapılarına inmek için null denetimleri işlemek için daha az kod yazmanıza yardımcı olur.
Örneğin:
// if 'customers' or 'Order' property or 'Price' property is null,
// dollarAmount will be 0
// otherwise dollarAmount will be equal to 'customers.Order.Price'
int dollarAmount = customers?.Order?.Price ?? 0;
Eski yol olmadan ? ve ?? bunu yapmak
int dollarAmount = customers != null
&& customers.Order!=null
&& customers.Order.Price!=null
? customers.Order.Price : 0;
ki bu daha ayrıntılı ve hantaldır.
Sadece eğlence için (hepinizin C # guys ;-) olduğunu bilmek.
Bence yıllardır var olduğu Smalltalk kökenlidir. Orada şöyle tanımlanır:
Nesnede:
? anArgument
^ self
UndefinedObject (aka nil'in sınıfı):
? anArgument
^ anArgument
Bunun hem değerlendiren (?) Hem de değerlendirmeyen versiyonları (??) vardır.
Genellikle ihtiyaç duyulana kadar sıfır bırakılan tembel olarak başlatılan özel (örnek) değişkenler için getter yöntemlerinde bulunur.
Buradaki birleştirmeyi kullanarak değer elde etmenin bazı örnekleri verimsizdir.
Gerçekten istediğiniz şey:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
veya
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
Bu, nesnenin her seferinde yeniden oluşturulmasını önler. Özel değişken null olarak kalır ve her istekte yeni bir nesne oluşturulursa, bu yeni nesne oluşturulursa özel değişkenin atanmasını sağlar.
??
kestirme değerlendirdi? yalnızca sıfır new FormsAuthenticationWrapper();
ise değerlendirilir . _formsAuthWrapper
Bütün bu konu ve diğerleri okudum ama bu kadar kapsamlı bir cevap bulamıyorum.
Bununla tamamen "neden kullanılır? Ve ne zaman kullanılır? Ve nasıl kullanılır ??" tamamen anladım.
Craig McMurtry tarafından Windows iletişim vakfı açıldı ISBN 0-672-32948-4
Birinin, bir değer türünün bir örneğine bir değer atanıp atanmadığını bilmek istediği iki yaygın durum vardır. Birincisi, örneğin bir veritabanındaki bir değeri temsil ettiği zamandır. Böyle bir durumda, veritabanında bir değerin gerçekten bulunup bulunmadığını tespit etmek için örneği incelemek isteriz. Bu kitabın konusuyla daha ilgili olan diğer koşul, örneğin bazı uzak kaynaklardan alınan bir veri öğesini temsil ettiği zamandır. Yine, örnekten o veri öğesi için bir değerin alınıp alınmadığını belirlemek ister.
.NET Framework 2.0, bir değer türünün bir örneğine null atamak ve örneğin değerinin null olup olmadığını sınamak isteyen, bunun gibi durumlar sağlayan genel bir tür tanımı içerir. Bu genel tür tanımı, T yerine değer türleriyle değiştirilebilecek genel tür bağımsız değişkenlerini kısıtlayan System.Nullable'dır. System.Nullable öğesinden oluşturulan tür örneklerine null değeri atanabilir; aslında, değerleri varsayılan olarak boştur. Bu nedenle, System.Nullable öğesinden oluşturulan türlere nullable değer türleri denebilir. System.Nullable, Value değeri null değilse, kendisinden oluşturulan bir türün örneğine atanan değerin alınabileceği bir değer olan bir özelliğe sahiptir. Bu nedenle, bir kişi şunları yazabilir:
System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}
C # programlama dili, System.Nullable öğesinden oluşturulan türleri bildirmek için kısaltılmış bir sözdizimi sağlar. Bu sözdizimi kişinin kısaltmasına izin verir:
System.Nullable<int> myNullableInteger;
için
int? myNullableInteger;
Derleyici, bir kişinin nullable değer türünün değerini sıradan bir değer türüne şu şekilde atamasını engeller:
int? myNullableInteger = null;
int myInteger = myNullableInteger;
Null olabilecek değer türünün bu durumda gerçekte sahip olacağı null değerine sahip olabilmesi ve bu değerin sıradan bir değer türüne atanamaması nedeniyle bunu önler. Derleyici bu koda izin verse de,
int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;
System.Nullable öğesinden oluşturulan tipe geçerli bir T değeri atanmamışsa, System.Nullable.Value özelliğine erişme girişimi geçersiz bir işlem olduğundan, ikinci ifade bir özel durumun atılmasına neden olur. durum.
Bir boş değer türünün değerini sıradan bir değer türüne atamanın uygun bir yolu, boş değer değeri türüne geçerli bir T değerinin atanıp atanmadığını belirlemek için System.Nullable.HasValue özelliğini kullanmaktır:
int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}
Başka bir seçenek de bu sözdizimini kullanmaktır:
int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;
Buna, sıradan tamsayı myInteger'a atanmışsa, sonuncusuna geçerli bir tamsayı değeri atanmışsa, boş değerli tamsayı "myNullableInteger" değeri atanır; aksi takdirde, myInteger öğesine -1 değeri atanır.
Üçlü bir operatöre benzer şekilde çalışan bir boş birleştirme operatörüdür.
a ?? b => a !=null ? a : b
Bunun bir başka ilginç yanı da, "Null olabilecek bir tür bir değer içerebilir ya da tanımsız olabilir" dir . Bu nedenle, boş olmayan bir değer türüne boş değer değeri atamaya çalışırsanız, derleme zamanı hatası alırsınız.
int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.
Yani bunu kullanarak ?? Şebeke:
z = x ?? 1; // with ?? operator there are no issues
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
eşittir
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
Ama bunun en güzel yanı, diğer insanların söylediği gibi onları zincirleyebilmeniz. Dokunulmayan tek şey, aslında bir istisna atmak için kullanabileceğinizdir.
A = A ?? B ?? throw new Exception("A and B are both NULL");
??
Operatör boş-kaynaştırma operatör denir. İşlenen boş değilse, soldaki işleneni döndürür; aksi takdirde sağ taraftaki işleneni döndürür.
int? variable1 = null;
int variable2 = variable1 ?? 100;
Set variable2
değerine variable1
eğer variable1
boş değil; aksi takdirde 100 olarak variable1 == null
ayarlayın variable2
.
Diğerleri Null Coalescing Operator
oldukça iyi tanımladı . İlgilenenler için bunun kısaltılmış bir sözdizimi vardır (SO sorusu):
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
buna eşdeğerdir:
FormsAuth ??= new FormsAuthenticationWrapper();
Bazıları onu daha okunaklı ve özlü bulur.