Soru işareti ve nokta operatörü ne yapar? C # 6.0'da ne demek?


359

VS2015 önizlemesinde C # 6.0 ile yeni bir operatöre sahibiz ?., bu şekilde kullanılabilir:

public class A {
   string PropertyOfA { get; set; }
}

...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
   //somecode
}

Bu tam olarak ne işe yarar?

Yanıtlar:


500

Bu var boş koşullu operatör. Temel olarak şu anlama gelir:

"İlk işleneni değerlendirin; bu boşsa, boş, bir sonuçla durun. Aksi takdirde, ikinci işleneni (ilk işlenenin üye erişimi olarak) değerlendirin."

Örnekte, nokta eğer olmasıdır aolduğunu null, daha sonra a?.PropertyOfAdeğerlendirecek nullbir istisna atma yerine - bu o karşılaştırır nullile referans foo(dize ait kullanılarak ==aşırı), bunlar eşit değiliz bulup infaz gövdesine gidecek ifaçıklamada .

Başka bir deyişle, şöyle:

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
    ...
}

... bunun dışında asadece bir kez değerlendirilir.

Bunun ifadenin türünü de değiştirebileceğini unutmayın. Örneğin, düşünün FileInfo.Length. Bu bir tür özelliğidir long, ancak bunu null koşullu işleçle kullanırsanız, bir tür ifadesiyle sonuçlanırsınız long?:

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

8
Boş koşullu operatör olarak adlandırılmıyor mu?
SLaks

1
@SLaks: Bunun "koşullu null" olduğunu düşündüm ama yanılmış olabilirim. Roslyn dil özellikleri belgelerini son kontrol ettiğimde, bu ad da değiştirilmemişti. Belki de kaynak buradaki otoritedir - kontrol edecektir.
Jon Skeet

3
@SLaks: Tabii. SyntaxKind'de görünüşe göre ikisi de rahatsız edici olmayan ConditionalAccessExpression ...
Jon Skeet

12
ismini "Elvis" operatörünü tercih ettim: P
Ahmed ilyas

3
Sadece kayıt için bu operatör için beş farklı isim gördüm: güvenli navigasyon, null koşullu, null yayılım, koşullu erişim, Elvis.
Gigi

81

Bir hiyerarşiyi düzleştirirken ve / veya nesneleri eşlerken çok yararlı olabilir. Onun yerine:

if (Model.Model2 == null
  || Model.Model2.Model3 == null
  || Model.Model2.Model3.Model4 == null
  || Model.Model2.Model3.Model4.Name == null)
{
  mapped.Name = "N/A"
}
else
{
  mapped.Name = Model.Model2.Model3.Model4.Name;
}

Gibi yazılabilir (yukarıdaki ile aynı mantık)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";

DotNetFiddle.Net Çalışma Örneği .

( ?? veya null birleştirme operatörü ? veya null koşullu işleçten farklıdır ).

Ayrıca Action ile atama operatörlerinin dış tarafında da kullanılabilir. Onun yerine

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}

Aşağıdakiler için basitleştirilebilir:

myAction?.Invoke(TValue);

DotNetFiddle Örneği :

Sistem kullanma;

public class Program
{
  public static void Main()
  {
    Action<string> consoleWrite = null;

    consoleWrite?.Invoke("Test 1");

    consoleWrite = (s) => Console.WriteLine(s);

    consoleWrite?.Invoke("Test 2");
  }
}

Sonuç:

Test 2


27
Ne ararken insanları kurtarmak için ?? null birleştirme operatörüdür ve null değilse Ad döndürür, aksi takdirde "N / A" döndürür.
Steve

6
@Erik Philips ben eklemek gerek || Model.Model2.Model3.Model4.Name == null dava aksi de aynı mantığı olması Model.Model2.Model3.Model4.Nameise null, mapped.Namekalacaknull
RazvanR

2
@ErikPhilips Sanırım aynı sayfada değil. Eğer hem durumlarda ne olacağını görmek için deneyin Model.Model2.Model3.Model4.Nameolduğunu null.
RazvanR

1
Sonuç "Yok", yine İLK YORUMU OKUYUN LÜTFEN. DotNetFiddle.Net Çalışma Örneği .
Erik Philips

7
@ErikPhilips: Bunun ilk yorumunuzla ilgisi yoktur, çünkü bu ilk örneğinizle ilgili değildir. elseBunda -branch atlamak ve sahip mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null, ikinci örnek yerine olurdu mapped.Name = "N/A". Bkz düzenlenmiş DotNetFiddle
Derm

3

Bu, yöntem zincirlemedeki null veya null olmayan değerlerle ilgili işlevleri çağırmamızı kolaylaştıran C # için nispeten yenidir .

aynı şeyi başarmanın eski yolu şuydu:

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

ve şimdi sadece daha kolay hale getirildi:

member?.someFunction(var someParam);

Burada okumanızı şiddetle tavsiye ederim:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

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.