Ne kadar 'var' ve null birleştirici operatör '??' okunabilirliği engellemeden eğlendirilecek misiniz?


23

Sorunun başlığının çok öznel olduğunu biliyorum, ancak ??aynı zamanda varyeni gelen kodlara başvururken çok mutlu / rahat olmadığım durumlarda, meslektaşlarım tarafından operatör kullanımıyla karşılaştım .

??İşleci kullanmak için verilen argüman kod okunabilirliğini ortadan kaldırıyordu.

Sorum şu, kullanmaya başladığınızda aynı şey olmuyor varmu?


49
Eğer bir "geliştirici" açık?? birleştirme operatörünü açıkladıktan sonra anlayamazsa, üretim koduna yakın bir yere izin verilmemelidir.
CaffGeek

12
Operatörü değiştirmemizi öneriyorum ?? IfNullThen için. ? IfSoChoose olabilir,: ElseChoose. + Ekleyin. - Çıkar, birleşmediği sürece Negatif. - Kullanmadan Önce Düşürme ve Sonra Kullanmayı Düşürme arasında bölünür. C ++ 'da bunu makrolarla yapabilirsiniz.
Lee Louviere

7
@ Xaade: Bu ironi değil mi? ... sağ? ... tanrı ironi olsun (ve ben bir ateistim).
Steven Jeuris

10
Olabilir @StevenJeuris alay , ama değil ironi .
Kirk Broadhurst

1
@KirkBroadhurst: Düzeltilmiş dururum , her zaman bu ikisini karıştırırdım.
Steven Jeuris

Yanıtlar:


53

Boş birleştirme operatörü (??)

Şahsen, bu operatörü kullanmanın hiçbir dezavantajı görmüyorum. 'Kolay' dan 'karmaşık' yeni işleçlere kadar aşağıdaki üç kod örneğini göz önünde bulundurun.

Sihir olmadan:

bool isNameSet = false;
string name;
if ( isNameSet )
{
    Console.WriteLine( name );
}
else
{
    Console.WriteLine( "No name set." );
}

Üçlü operatör:

bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );

Boş birleştirme:

string name = null;
Console.WriteLine( name ?? "No name set." );

Bu operatörlerin icat edilmesinin nedeni çok yaygın programlama işlemlerini temsil etmeleridir . Onları kullanmak istememek, çünkü onlara alışık değilsiniz, sadece inatçı olmaktır . Diller gelişir, özellikler gelişir, onları kullanmayı öğrenir!

var anahtar kelime

Var anahtar kelimesi hakkında biraz farklı düşüncelerim var. Bir değişkenin türü genellikle kodunuz hakkında ek bilgi verir. Var anahtar sözcüğünü kullanarak türü gizlemeyi buluyorum, bazen kodu daha az okunabilir hale getiriyor. Otomatik tamamlama kullanmadan veya gerçekte ne olduklarını görmek için tanımlayıcıların üzerine gelmeden ne bekleyeceğinizi daha az biliyorsunuz. Benim düşünceme göre, bu okuma / yazma daha yavaş kod ile sonuçlanır.

Türün fazladan bilgi vermediğini tespit ettiğimde anahtar kelimeyi kullanıyorum.

  • Temelde , Resharper'dan öğrendim, orada bir ortam olduğu için foreach döngülerinde . Çoğu zaman, ne tür bir koleksiyona girdiğinizi biliyorsunuzdur, bu nedenle koleksiyondan öğeler beklediğinizi biliyorsunuzdur.
  • Linq sorguları . Linq sorgularının sonucu genellikle çok karmaşık genel türlerdir. Bu türün gösterilmesi yarardan çok zarar verir.
  • Yapıcılarıyla basitçe başlatılan uzun yazım adları. Yapıcıya bakarak türün ne olduğunu zaten söyleyebilirsiniz.

Son ifadeye örnek olarak:

ThisIsSomeSpecializedTypeRightHere duplication =
    new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
    new ThisIsSomeSpecializedTypeRightHere();  // Less duplication.

// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();

24
Bu son örnek tam olarak var anahtar sözcüğünün excel olabileceği durumdur. Bu kodun kodunuz boyunca karıştırıldığını hayal edin. Factory.CreateSomeTypedöner IEnumerable<SomeType>. Bir gün, hangi nedenle olursa olsun, geri dönüşü değişir SomeType[]. Var kullandıysanız, sadece bir derleme.
pdr,

1
Bu örnek yanlış yoldan geldi ve sonra yiyecek bulmaya gittim. Numpty! Daha iyi bir örnek seninkini kullanmak olabilir. Ya bir Factory.CreateSomeType()değişiklik yapacaksa ISomeType?
pdr,

4
pdr: Bu en büyük olasılıkla arayüzün de değiştiği ve davranışların da ayarlanması / eklenmesi gerektiği anlamına geliyor. Bu basit bir isimse, elbette ki otomatik yeniden adlandırma işlemini yaptınız. Eğer 'sözleşme' değişirse, kodumu ihlal etmeyi tercih ederim, böylece bir şeyleri düzeltmem gerekip gerekmediğini görebilirim.
Steven Jeuris

2
Beton tipini geri getirmenin bir arayüze dönüşmesi durumunda, sadece aynı arayüze sahip diğer beton tiplerine izin vermesi (Fabrika modeliyle tutarlı) olması daha muhtemel olduğunu düşünüyorum. Ancak sözleşme değişirse kodunuz bozulur - ancak her yerde değil, sadece önemli olduğu birkaç durumda kırıldığını görebilirsiniz.
pdr,

1
@ Tom Hawtin, hepimiz biliyoruz ki nulltamamen kaçınmak kaçınılmazdır . Dahası, alternatifleri nullne kadar çok ararsam, o kadar fazla fark ettim nullki bazen en temiz çözüm olur. Benim verdiğim örnek o kadar kötü değil IMHO ve null türlerinin uygun bir kullanımını buluyorum.
Steven Jeuris

16

var okunabilirliği artıran daha az ayrıntılı kod sağlar. Bence okunabilirlik kaç ayrıntı gördüğünüzle ölçülmemeli, ilk bakışta kaç ayrıntı gizlendi. Linq örneklerinin yanı sıra, aşağıdaki örnek verildiğinde, kaynak kod düzeyinde ördek yazmaya izin verir:

...
foreach (var message in messages) {
  var label = Factory.CreateLabel();
  label.Text = message;
  Controls.Add(label);
}
...

Text özelliğini sağladığı sürece etiket türünün ne olduğu kimin umrunda?


Birinin bunun örneğin bir winforms etiketi mi yoksa WPF etiketi mi olduğunu anlamaya çalışması.
Steven Jeuris

14
@Steven Jeuris: Bu genellikle bilinen bir içerik bilgisidir. Değilse, koda yanlış bir şekilde yaklaşıyorsunuzdur.
Kod

Varsayılan bir WPF etiketi mi yoksa özel bir etiket mi olduğunu bilmek isteyen biri mi? :)
Steven Jeuris

14
1. Bu, bir Text özelliğine sahip bir etiket olduğu sürece, gerçekten ilgilenmeli mi? 2. Bu, GERÇEKTEN DOĞRU YAPMAK İÇİN ÇALIŞMALARININ iyi bir nedeni varsa, Intellisense'e sorun. 3. Intellisense olmadan bir IDE'de kod düzenliyorlarsa, muhtemelen 'var' :) 'den çok daha büyük
güçlükleri vardır

4
Zayıf bir soyutlama duygusu olan biri.
Jim Balter

16

??Operatör hakkında ciddi bir yorumum yok , çünkü böyle bir operatörle hiçbir zaman ağır bir dil kullanmadım. İlgili var, insanlar tüm tamamen örtülü yazarak zaman var Yakut, Python, Perl ve PHP gibi dillerde programlamak. Bu dillerin yerlileri, bir değişkenin biçimsel tipinin genellikle alakasız gürültü olduğunu fark eder. Değişkenin neler yapabileceği ile daha çok ilgileniyorsunuz , yani yapısal / ördek arayüzü.

Benzer şekilde, çoğunlukla D de programlarım. D statik olarak yazılır, ancak buna autoeşit olan anahtar kelimeye sahiptir var. Derleyicinin okuyucusuna veya (dolaylı dönüşüm yoluyla) bir şeyin türünü vurgulamanız gerekmedikçe, her yerde kullanmanın deyimsel olduğu düşünülmektedir. Bir fonksiyon dönüş tipi olarak kullanılmadığı zamanlar dışında (buna D'de izin verilir), bunu programlama sırasında çoğunlukla resmi / aday türler yerine yapısal / ördek arayüzleri açısından düşünürüm çünkü okunabilirliği engellemedik.

Ayrıca, IMHO varmümkün olan her yerde kullanımı DRY'ye iyi bir örnektir. Bir şeyin türü tek bir yerde belirtilmeli ve ardından ne zaman yayılması gerektiğine göre otomatik olarak çoğaltılmalıdır. Eğer kullanıyorsanız varve bir noktada değişikliğe değişken ihtiyaçlara biçimsel tipi, gerekli değişiklikler otomatik olarak program sürece derleyici tarafından her yerde gerekli aktarılacaktır tip-doğru değil, programcı daha elle her örneğini değiştirmek zorunda hala . Bu iyi bir şey (tm).


13

Sonunda takım için bu bir soru olduğunu düşünüyorum. Eğer ekibimdeki hiç kimseye okunamazsa, onları örneklerle ikna etmek ya da daha okunaklı buldukları analago kısaltmaları (+ = gibi) vurgulayarak birkaç kez deneyebilirim, ancak kullanmayacağım.

Ancak, yalnız çalışıyorsanız o zaman buluyorum? ve sınırsız bir şekilde okunabilir şekilde değişkenlik gösterebilir. Üstelik

var a = b ?? c ?? d ?? e ?? "";

bana oldukça açık.

Üçlü operatörler ve dynamicelbette farklı bir konudur.


4
Burada `String.Empty'yi kullanırdım.
Meslek

1
@Job, dürüstçe, ben de ben :) şey düşünemedim o zaman, bu dizede bir şey koymak gidiyordu olur
pdr'lik

4
var a = b ?? c ?? d ?? e ?? String.Empty ?? "";
Lee Louviere

2
@Xaade Asla yeterince emin olamazsınız. Ama gerçekten, String.Empty veya "" kullanmak kişisel bir tercihtir. ""
Kullanıyorum

12
@Xaade - Bir String.Emptydaha dönerse null, çok fazla bozuk kodun içindeyiz.
Jesse C. Dilimleyici

10

Kullanmak için verilen argüman ?? Operatör kodda okunabilirliği ortadan kaldırıyordu.

Bu konuda kısaca düşündüğümde, bu yorum bana yorum yapan kişiye, söylemesi gerektiği kadar iyi anlamadığını söyler. Büyük olasılıkla belirli durumlarda doğrudur, ancak genel olarak, C # ekibinin "okunabilirlik" nedeniyle ekleyebileceği kadar önemli olduğunu düşündüğü bir şeyi iskonto etmem. Bunu aynı kategorideki if(boolean_object)vs'ye koydum if(boolean_object == true). Bazı insanlar ikincisinin daha okunaklı olduğunu savunuyor, ancak gerçekte birisinin okuması / yazması için ekstra kod ekliyor ve bazı durumlarda daha kafa karıştırıcı olabilir (düşün if(boolean_object != false))

Sorum şu, var kullanmaya başladığınızda aynı şey olmuyor mu?

C # ekibi ne olacağını bildiğin bir şeyi tanımlamamanı sağladı. Bir değişkenin ne olacağını kesinlikle tanımlamam gerekmiyorsa (dönen nesnenin x türünde olması veya gerçekten okunaklı olmaması kesinlikle önemlidir) kullanıyorum var. var x = "MY_STRING";Bakmanın bir ip olduğunu biliyorum. Gerçekte, yapmam gerekeni yaptığı sürece bir sicimin umrunda değil. Değişken türünü tanımlamak derleyicinin değil, benim yararım içindir. Bir şey yanlışsa, yanlış değişken türüne sahipsem derleyici ne zaman çalıştığını söyleyecektir.


0

varLINQ sorguları - Anahtar kelime, benim görüşüme göre, bu orijinal tanıtıldı olduğu için durumlarda kullanılır bested. Bu sorgularda, döndürülen sonucun türü genellikle zamanından önce belirlenmesi zor olan ve okuyucunun kodunuzun ne yaptığını anlamalarına yardımcı olmayan büyük ve karmaşık bir ada sahiptir.

Ancak, yapmak var text = "Some text " + variableName + "some more text."sadece tembel.

EDIT: @Jorg Kasten basit bir cevapla atladın ama tartışmaya hiçbir şey eklemedin. Tamam, daha iyi bir örnek için buna ne dersiniz: var items = doc.DocumentElement.FirstChild.ChildNodes;Bundan türünü anlayabiliyorsanız, size bir çerez vereceğim.


18
Bunu anlamaya yapamıyorsanız "Some text "bir olduğunu string, o zaman yaklaşık sayısından daha endişe için çok daha büyük sorunları var varKodunuzdaki s.
Jörg W Mittag

3
Sorun değil var; sorun, crappy değişkeninin adı "items". İyi bir değişken adı kullanıyorsanız, yanlış bir şey yok var.
Kyralessa

3
(Bakmadan) öğelerin, bir XML düğümleri koleksiyonunun tüm özelliklerine ve yöntemlerine sahip olmayı umduğum bir XML düğümleri topluluğu olduğunu tahmin ediyorum ve gerçekten bilmem gereken tek şey bu.
KutuluMike

Var türünün ne anlama geldiğini ve derhal bakarak söyleyemediğinizi bilmeniz gerekiyorsa, fareyi üzerine getirin. Bunu yapmak için pek bir şey bulmuyordur.
scrwtp

1
"sadece tembel" - Bu ona karşı bir tartışma değil. Aslında, hiç akıllı değil.
Jim Balter

0

Var kullanımıyla ilgili temel bir sorunum var.

Bu örnekte her şey yan yana olmakla birlikte, sorun gerçekten paylaşılan kütüphaneler veya projelerle ilgili büyük çözümler ile ilgilidir.

Bunu düşün:

public MyFirstObject GetMeAnObject() {
    return new MyFirstObject();
}

public void MainProgram() {
    var theObject = GetMeAnObject();
    theObject.PerformOperation();
}

GetMeAnObject bir başkası tarafından ihtiyaçlarına göre değiştirilirse ne olur?

public MySecondObject GetMeAnObject() {
    return new MySecondObject();
}

MainProgram yönteminin .PerformOperation () üzerinde büyük bir kırmızı hatası olur. Ne oldu? PerformOperation daha önce mükemmel bir şekilde çalıştı. Hedef üzerindeki yöntemlere bakıyoruz ve iz bırakmadan kayboldu. Geçen sefer oradaydı ve bu yönteme ihtiyacımız var. Kuyruğunu kovalayıp uzun zaman harcayabilir ve MyFirstObject'in PerformOperation adlı bir metodu varsa, neden görülemeyeceğini anlamaya çalışabilirsiniz. Herkes GetMeAnObject'in bir MyFirstObject döndürdüğünü "bilir", bu yüzden bunu kontrol etmenin bir anlamı yok.

Açıkça theObject yazmış olsaydı, o zaman GetMeAnObject'i çağıran satırda bir Geçersiz Döküm hatası olur ve GetMeAnObject'in beklediğiniz gibi olmayan bir tür döndürdüğü açıkça görülebilir.

Kısacası, açık beyan, hataların ne anlama geldiğini bildiğiniz anlamına gelir. Geçersiz bir döküm, bir tür beklediğiniz ve başka bir türün döndürüldüğü anlamına gelir. Tanınmayan bir üye, üyenin tanınmadığı anlamına gelir.


10
Bir meslektaş, testlerde bulunmayan kodda bir değişiklik yaptı ve sizce sorunun öyle varmi? Dilin bu tür davranışlara karşı korunması beklenemez - ya MyFirstObject'i doğrudan değiştirdilerse? Yine de kırılırdı, ancak hiçbir sözdizimi sizi bundan kurtaramazdı. Bunun bir gücü olduğunu varbile düşünürdüm : peki ya MySecondObject'i iade etmek yerine şimdi IMyFirstObject'i iade ediyor olsaydınız?
Phoshi

2
"Herkes" biliyor "GetMeAnObject bir MyFirstObject döndürüyor, bu yüzden bunu kontrol etmenin bir anlamı yok." Aslında programlamada, hata ayıklama durumunda ne GetMeAnObject'in hafızasına bağlı olacağıma dair bir senaryo düşünemiyorum. PerformOperation'un orada olmadığını kontrol edersem, kodu görürdüm ve başka bir sınıf için değil. Eğer bir IDE'de sınıf açılırsa, nesnenin türüne bakarım. Aslında, derleyici bana hatayı söylediğinde, 'MySecondObject sınıfı hiçbir PerformOperation işlemi yok' derdi. Bu herkes için nasıl biliyor?
Muhammad Alkarouri
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.