Nedir ?[]? C # sözdizimi?


85

Ben ders çalışırken temsilci olan soyut bir sınıf aslında Delegate.cs, ben şu yöntemi hangi anlamıyorum gördü

  • Dönüş değeri neden ?zaten bir başvuru ( sınıf ) türü olsa da kullanılıyor?
  • ?[]? parametredeki anlam

Açıklayabilir misiniz?

public static Delegate? Combine(params Delegate?[]? delegates)
{
    if (delegates == null || delegates.Length == 0)
        return null;

    Delegate? d = delegates[0];
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}


23
Sıfırlanabilir değerler içerebilen null olabilecek bir dizi değil mi?
Cid

3
c # 8, şimdi bir nesne değişkeninin boş olmasına izin verilmeyeceğini belirtebilirsiniz. O derleyici bayrağı çevirmek ise, her değişken belirtmek zorunda olan boş izin verdi.
Jeremy Lakeman

Yanıtlar:


66

Adım adım açıklama:

params Delegate?[] delegates - Null olabilecek bir dizi Delegate

params Delegate?[]? delegates - Dizinin tamamı boş bırakılabilir

Her parametre türünde olduğundan Delegate?ve Delegate?[]?dizinin bir dizinini döndürdüğünüzden, dönüş türünün başka Delegate?türlü olması mantıklıdır, aksi takdirde derleyici, sanki geri çekiliyormuş gibi ve intbir dize döndüren bir yöntemden bir hata döndürür.

Örneğin, kodunuzu aşağıdaki Delegategibi bir tür döndürecek şekilde değiştirebilirsiniz :

public static Delegate Combine(params Delegate?[]? delegates)
{
    Delegate defaulDelegate = // someDelegate here
    if (delegates == null || delegates.Length == 0)
        return defaulDelegate;

    Delegate d = delegates[0] ?? defaulDelegate;
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}

4
ilk sorum ne olacak? Dönüş değeri neden ?zaten referans (sınıf) türü olsa da kullanılır
snr - Reinstate Monica

2
Çünkü d delege olan Delegate? yazın. Ve ayrıca parametrelere bağlı olarak null veya Delege
Athanasios Kataras

2
@snr Dönüş değeri ?, argüman değerinin ?. İkincisini anlarsanız, öncekini otomatik olarak anlarsınız. Yöntem null değerini döndürebileceğinden , parametre null değerini kabul edebilir . Yani, ikisi de boş olabilir .
GSerg

2
Ben dokundum. Ben sadece örnekle ikinci bölüm olarak cevapladım. Since each parameter is of the type Delegate? and you return an index of the Delegate?[]? array, then it makes sense that the return type is Delegate?
Athanasios Kataras

2
@snr: Dönüş değeri neden kullanılıyor? zaten referans (sınıf) türü (1) olsa da, benzer kodda yapılar da kullanılıyorsa, bir alışkanlık veya yeniden düzenleme kalıntısı olabilir (2) C # 8'de referans türlerinin doğası gereği nullable ( 3) Foo?temiz bir HasValueözelliğe sahiptir, ancak kontrol edilmesi Foogerekir == null(4) Yöntem imzasını okuyan geliştiricilere null'lerin mümkün, beklenen ve doğru bir sonuç olduğunu bildirir. (5) Kod, Bu konuda açık çok nullability düşkün ve varlık olduğunu.
flater

25

Nullable Reference Türleri C # 8.0'da yenidir, daha önce yoktur.

Bu bir dokümantasyon meselesi ve derleme zamanında uyarıların nasıl üretildiği.

"Nesne bir nesnenin örneğine ayarlanmadı" özel durumu istisnadır. Ancak bu bir çalışma zamanı istisnasıdır, derleme zamanında kısmen keşfedilebilir.

Bir düzenleme Delegate diçin her zaman arayabilirsiniz

 d.Invoke();

yani, kodlayabilirsiniz, derleme zamanında hiçbir şey olmayacak. Çalışma zamanında istisnalar oluşturabilir.

Yeni bir Delegate? pKod için

 p.Invoke();

derleyici uyarısı verir. CS8602: Dereference of a possibly null reference sen yazmadıkça:

 p?.Invoke();

ne demek, sadece boş değilse arayın.

Yani bir değişkenin null içerebileceğini veya içermeyebileceğini belgelersiniz. Uyarıları daha erken artırır ve null için birden fazla testten kaçınabilir. Aynı int ve int için ne var ?. Kesinlikle biliyorsunuz, biri boş değil - ve diğerini nasıl dönüştüreceğinizi biliyorsunuz.


bilmediğiniz uyarıyla Delegateboş değil. Sadece bildiğinizi iddia ediyorsunuz (çoğu durumda yeterince iyi).
Tim Pohlmann

@TimPohlmann int i = null değerinin yanı sıra s = null değeri de imkansızdır (C # 8'de bu kırılma değişikliğiyle). Yani bir şey yapmaktan biraz daha fazlası. Geriye dönük uyumluluk için uyarıyla indirgenmiştir. Uyarıyı bir hataya yükseltirseniz, bunun boş olmadığından emin olabilirsiniz.
Holger

4
En son kontrol ettiğimde NRT'ler% 100 kurşun geçirmez değil. Derleyicinin algılayamadığı bazı kenar durumlar vardır.
Tim Pohlmann

Evet, ancak bu "değişken başlatılmadı" veya "bir değer döndüren tüm kod yolları değil" uyarılarıyla aynıdır. Bunların tümü, çalışma zamanında algılanmadan% 100 derleme zamanı özellikleridir. İnt? 'Den farklı olarak, ekstra bilgi tutmak için fazladan bellek eklemediklerini düşünüyorum. Diyelim ki akıllı olduğu kadar güvenilir. Oldukça iyi.
Holger

1
Eğer varsa int, asla boş olamaz. Eğer varsa, Delegateboş olabilir (çeşitli nedenlerle, örneğin yansıma). Delegate(NRT etkinken C # 8'de) null olmadığını varsaymak genellikle güvenlidir , ancak asla kesin olarak bilemezsiniz (kesin olarak nerede intbildiğimizi).
Tim Pohlmann

5

C # 8'de referans türlerini açıkça boş değer olarak işaretlemelisiniz.

Varsayılan olarak, bu türler null türlerini içeremez, bu da değer türlerine benzer. Bu, başlık altında işlerin nasıl çalıştığını değiştirmese de, tip denetleyicisi bunu manuel olarak yapmanızı gerektirir.

Verilen kod C # 8 ile çalışmak için yeniden düzenlenmiştir, ancak bu yeni özellikten faydalanmamaktadır.

public static Delegate? Combine(params Delegate?[]? delegates)
{
    // ...[]? delegates - is not null-safe, so check for null and emptiness
    if (delegates == null || delegates.Length == 0)
        return null;

    // Delegate? d - is not null-safe too
    Delegate? d = delegates[0];
    for (int i = 1; i < delegates.Length; i++)
        d = Combine(d, delegates[i]);

    return d;
}

İşte bu özellikten yararlanan güncellenmiş bir kod örneği (çalışmıyor, sadece bir fikir). Bizi bir sıfır denetiminden kurtardı ve bu yöntemi biraz basitleştirdi.

public static Delegate? Combine(params Delegate[] delegates)
{
    // `...[] delegates` - is null-safe, so just check if array is empty
    if (delegates.Length == 0) return null;

    // `d` - is null-safe too, since we know for sure `delegates` is both not null and not empty
    Delegate d = delegates[0];

    for (int i = 1; i < delegates.Length; i++)
        // then here is a problem if `Combine` returns nullable
        // probably, we can add some null-checks here OR mark `d` as nullable
        d = Combine(d, delegates[i]);

    return d;
}

2
those types are not able to contain null, hata değil derleyici uyarısı oluşturduğunu unutmayın . Kod iyi çalışır (ancak NullReferenceExceptions oluşturabilir). Bu geriye dönük uyumluluk göz önünde bulundurularak yapılır.
JAD
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.