Tek satırlı yöntemlerde dönüş değeri hesaplamasını ve return ifadesini bölme?


26

Bir iş arkadaşınızla bir returnifadeyi kırma ve dönüş değerini iki satırda hesaplayan ifadeyle ilgili bir tartışma yaptım .

Örneğin

private string GetFormattedValue()
{
    var formattedString = format != null ? string.Format(format, value) : value.ToString();
    return formattedString;
}

yerine

private string GetFormattedValue()
{
    return format != null ? string.Format(format, value) : value.ToString();
}

Kod bilge Ben ilk değişkende bir değer göremiyorum. Benim için ikincisi, özellikle kısa olan yöntemler için daha net. Yine de, eski varyantın hata ayıklamanın daha kolay olduğu iddiası - ki bu oldukça küçük bir değer, çünkü VisualStudio bize, yürütme bir kırılma noktası nedeniyle durdurulduğunda ifadelerin ayrıntılı bir şekilde incelenmesini sağlıyor.

Sorum şu ki, hala hata ayıklamayı kolaylaştırmak için kodu daha az net bir şekilde yazmak geçerli bir noktaysa? Bölünmüş hesaplama ve ifadeye sahip değişken için başka argüman var returnmı?


18
VS üzerinde çalışmamak, ancak karmaşık bir ifadeye koşullu bir sınırlama noktası koyamayacağınızı varsaymak (ya da girmek karmaşık olurdu), bu nedenle muhtemelen sadece rahatlık için atama ve ayrı ifadelere geri dönecekti. Derleyici zaten her ikisi için de aynı kodla gelecektir.
17'de

1
Bu muhtemelen dile bağlıdır, özellikle değişkenlerin işaretçi davranışı yerine (muhtemelen karmaşık) nesne davranışının olduğu dillerde. @ Paul K ifadesi, muhtemelen işaretçi davranışına sahip diller, nesnelerin basit değer davranışına sahip dilleri ve olgun, yüksek kaliteli derleyicileri olan diller için doğrudur.
MSalters

4
"VisualStudio bize ifadelerin çok detaylı bir incelemesini sağladığından, yürütme bir kesme noktası nedeniyle durdurulduğunda" - öyle. Öyleyse, işlev birden fazla üyeli bir yapı döndürdüyse, dönüş değerini nasıl elde edersiniz? (ve bu özelliğin desteği en iyi durumdadır, dönüş değerini hiç alamadığınız birçok kombinasyon vardır).
Voo

2
Birinin BUGÜN kullanıyorsanız, hata ayıklayıcısında "ifadelerin ayrıntılı incelemesi" nasıl yapıldığında, kodun yazılmasının kötü bir seçenek haline gelmesi, HERHANGİ bir hata ayıklayıcısında hata ayıklamanın kolay olmasını nasıl sağlar?
Ian,

16
Tüm işlev gövdesini azaltarak onu daha da kızdırınprivate string GetFormattedValue() => string.Format(format ?? "{0}", value);
Graham,

Yanıtlar:


46

Değişkenleri açıklamak, karmaşık ifadeleri daha iyi okunabilir kılmak için yardımcı olabilecek iyi bilinen bir yeniden yapılandırmadır . Ancak, gösterilen durumda,

  • ek değişken, çevreleyen yöntem adından net olmayan hiçbir şeyi “açıklamaz”.
  • deyim daha da uzar, böylece (biraz) daha az okunabilir

Dahası, Visual Studio hata ayıklayıcısının daha yeni sürümleri, çoğu durumda gereksiz bir değişken getirmeden bir işlevin dönüş değerini gösterebilir (ancak dikkat edin, bazı uyarılar var, bu daha eski SO yazısına ve farklı cevaplara göz atın ).

Dolayısıyla, bu özel durumda, size katılıyorum, ancak açıklayıcı bir değişkenin gerçekten kod kalitesini artırabileceği başka durumlar da var.


Ben de kesinlikle bunun yararlı olduğu durumlar olduğu konusunda hemfikirim .
Paul Kertscher

2
Ben genellikle resultdeğişkenin adı olarak kullanırım . Çok uzun
sürmez

26
@ edc65: result sıkça olduğu gibi genel bir ad, yalnızca koda ses ekler ve nadiren okunabilirliği arttırır, bu da tam olarak cevabımın noktasıdır. Bu hata ayıklamaya yardımcı olduğu bağlamda haklı gösterilebilir, ancak ayrı bir değişkene gerek duymayan bir hata ayıklayıcı kullanırken kaçınacağım.
Doktor Brown,

6
@JonHanna bana göre uzun aracı. İsim result, bunun fonksiyondan kaynaklanan değer olduğu bilgisini taşır, böylece fonksiyon dönmeden önce ona bakabilirsiniz.
edc65

1
@ edc65 ama bu kullanışlı görünmesini sağlar. Şimdi kodunuzu okuduğumda hemen farkına varmıyorum. Böylece kodunuz daha az okunabilir hale geldi.
Jon Hanna

38

Gerçekleri göz önüne alındığında:

a) Derleyici değişkeni en iyi duruma getirdiği için son kod üzerinde bir etkisi yoktur.

b) Ayrı olması hata ayıklama kapasitesini arttırır.

Şahsen ben onları zamanın% 99'unu ayırmanın iyi bir pratik olduğu sonucuna vardım.

Bu şekilde yapmanın hiçbir dezavantajı yoktur. Kodu kabarttığı argümanı yanlış bir isimdir, çünkü şişirilmiş kod okunamayan veya hata ayıklanması zor kodla karşılaştırıldığında önemsiz bir konudur. Ayrıca, bu yöntem kendi başına kafa karıştırıcı kod oluşturamaz, bu tamamen geliştiriciye bağlıdır.


9
Bu benim için doğru cevap. Bu, kesme noktası ayarlamayı ve hata ayıklama sırasında değeri görmeyi kolaylaştırır ve farkında olduğum bir olumsuz tarafı yoktur.
Matthew James Briggs

B noktası için, Visual Studio Kodunda, dönüşe yalnızca kesme noktasını koyun ve sonra şu ifadeyi ekleyin: GetFormattedValue () ve kesme noktasına basıldığında sonuç gösterilir, bu yüzden fazladan satır gerekmez. Ancak yerel halkı fazladan bir çizgiyle görmek daha kolaydır, çünkü hata ayıklayıcısına herhangi bir ek ifade eklenmesini gerektirmez. Yani, gerçekten kişisel tercih meselesi.
Jon Raynor

3
Dönüş değeri için @JonRaynor, kesme noktasını fonksiyonun kapatma braketine koyun. Birden fazla geri dönüşe sahip işlevlerde bile, döndürülen değeri yakalar.
Baldrickk

16

Genellikle, sadece bir sonucu isimlendirmek için bir değişken eklemek kodun daha fazla belgelenmesini sağladığında çok yararlıdır. Bu durumda, değişken ismi metod adına çok benzeyen bir faktör değildir.

Bir satır yönteminin içsel bir değeri olmadığını unutmayın. Bir değişiklik daha fazla satır getirir ancak kodu daha net yaparsa, bu iyi bir değişikliktir.

Ancak genel olarak, bu kararlar kişisel tercihlerinize oldukça bağlıdır. Örneğin her iki çözümü kafa karıştırıcı buluyorum çünkü koşullu operatör gereksiz yere kullanılıyor. Bir if ifadesini tercih ederdim. Ancak takımınızda farklı sözleşmeler konusunda anlaşmış olabilirsiniz. Öyleyse sözleşmelerin önerdiğini yapın. Eğer sözleşmeler böyle bir durumda sessizse, bunun uzun vadede önemli olmayan son derece küçük bir değişiklik olduğuna dikkat edin. Bu desen tekrar tekrar meydana gelirse, belki bir ekip olarak bu vakalarla nasıl başa çıkmak istediğinizi tartışabilirsiniz. Ancak bu, kılları “iyi kod” ve “belki biraz daha iyi kod” arasında bölmektir.


1
"Her iki çözümü de kafa karıştırıcı buluyorum çünkü koşullu operatör gereksiz yere kullanılıyor." - Gerçek bir dünya örneği değil, çabucak bir şeyler yapmak zorunda kaldım. Kuşkusuz bu en iyi örnek olmayabilir.
Paul Kertscher

4
Temelde bunun “radar altında” bir fark olduğunu söylediği için +1 (diğer şeylerin eşit olması) rahatsız edilmeye değmez.
TripeHound

3
@Mindwin, üçlü operatörü kullandığımda, genellikle birden fazla satıra bölerim, böylece gerçek durumun ne olduğu ve yanlış durumun ne olduğu açıktır.
Arturo Torres Sánchez

2
@ ArturoTorresSánchez Ben de yapıyorum, fakat a ?ve yerine :kullanıyorum if() {ve } else {- - - - \\ :)
Mindwin

3
@Mindwin, ancak bir ifadenin ortasındayken (nesne başlatıcı gibi) bunu yapamam
Arturo Torres Sánchez 16

2

Sorularınıza cevap olarak:

Sorum şu ki, hala hata ayıklamayı kolaylaştırmak için kodu daha az net bir şekilde yazmak geçerli bir noktaysa?

Evet. Aslında, önceki ifadenizin bir kısmı bana (darmadağın değil) biraz kısa görüşlü gibi görünüyor (aşağıda kalın): "Ne var ki, eski varyantın hata ayıklamak daha kolay olduğu iddiası - VisualStudio’dan bu yana oldukça küçük bir değer Uygulama bir kırılma noktası nedeniyle durdurulduğunda ifadelerin çok detaylı bir şekilde incelenmesini sağlıyor. "

Hata ayıklamayı kolaylaştırmak (neredeyse) asla " küçük değer " anlamına gelmez, çünkü bazı tahminlere göre bir programcının zamanının% 50'si hata ayıklamaya harcanır ( Tersinir Hata Ayıklama Yazılımı ).

Bölünmüş hesaplama ve return deyimiyle değişken için başka argüman var mı?

Evet. Bazı geliştiriciler, bölünmüş hesaplamanın okunmasının daha kolay olduğunu savunuyorlardı. Bu, elbette, hata ayıklamaya yardımcı olur, ancak birisinin kodunuzun uygulayabileceği veya uygulayabileceği iş kurallarını deşifre etmeye çalıştığında da yardımcı olur.

NOT: İş kuralları, sıklıkla değişebildiklerinden bir veritabanında daha iyi sunulabilir. Bununla birlikte, bu alandaki net kodlama hala çok önemlidir. ( Bir İş Kuralları Motoru Nasıl Kurulur )


1

Daha da ileri gideceğim:

private string GetFormattedValue()
{
    if (format != null) {
        formattedString = string.Format(format, value);
    } else {
        formattedString = value.ToString()
    }
    return formattedString;
}

Niye ya?

Üçlü işleçlerin daha karmaşık mantık için kullanılması okunmaz olur, bu nedenle daha karmaşık ifadeler için yukarıdaki gibi bir stil kullanırsınız. Bu tarz her zaman kullanıldığında, kodunuz bir insanın ayrıştırması için tutarlı ve kolaydır. Ek olarak, bu tür tutarlılığı tanıtarak (ve kod çizelgelerini ve diğer testleri kullanarak) yazım goto failhatalarını önleyebilirsiniz .

Başka bir avantaj, kod kapsamı raporunuzun bir test eklemeyi unuttuysanız size bildirilmemesidir format. Üçlü operatör için durum böyle olmaz.


Tercih edilen alternatifim - "olabildiğince hızlı bir şekilde geri dönüş elde edersen" iseniz ve bir yöntemden birden fazla iadeye karşı değilseniz:

private string GetFormattedValue()
{
    if (format != null) {
        return string.Format(format, value);
    }

    return value.ToString();
}

Böylece, varsayılanın ne olduğunu görmek için son dönüşe bakabilirsiniz.

Yine de tutarlı olmak önemlidir - ve tüm metotlarınızın birini veya başka bir sözleşmeyi izlemesini sağlayın.


1
İlk örnek, kötü bir uygulama gibi görünüyor çünkü value.ToString()format boş olmadığı zaman gereksiz yere çağrılıyor. Genel durumda, bu önemsiz olmayan hesaplamaları içerebilir ve bir biçim dizesi içeren sürümden daha uzun sürebilir. Örneğin, valuePI'yi bir milyon ondalık basamağa depolayan ve yalnızca ilk birkaç basamağı isteyen bir format dizesini düşünün .
Steve

1
neden private string GetFormattedValue() => string.Format(format ?? "{0}", value); aynı değil ve hata ayıklayıcısına güvenmek yerine doğruluğu sağlamak için birim testleri kullanın.
Berin Loritsch

1
Bir üçlünün daha az net olabileceği konusunda hemfikir olsam da , boş sonlandırıcı işleri daha net hale getirebilir . En azından bu durumda.
Berin Loritsch

1
Sevgili günlük, bugün iyi bilinen (yaklaşık 40 yıldır var olan) paradigmalar, deyimler ve operatörler kullanarak açık ve özlü kod yazmanın, alıntı, zekice çift alıntı olmaktan ziyade çift alıntı yapmak, alıntı yapmaktan ziyade, aşırı derecede ayrıntılı kod ihlali yazmak olduğunu okudum. KURU ve söz konusu operatörleri, deyimleri ve paradigmaları kullanmamak, bunun yerine, önceden programlama geçmişine sahip olmayan sadece beş yaşına kadar muhtemelen şifreli olabilecek bir şeyden kaçınmaya çalışmaktır - bunun yerine açıklık vardır . Kahretsin, çok yaşlanmış olmalıyım, sevgili günlüküm ... Şansım varken Go'yu öğrenmeliydim.
vaxquis

1
"Üçlü operatörlerin daha karmaşık bir mantık için kullanılması okunmaz olur" Bu gerçekten de geçerli (ve insanları karmaşık bir mantık görmüştüm), bu OP'nin kodu için doğru değildir ve ayrıca üçlü operatörlere özel bir şey değildir. Güvenle söyleyebileceğim tek şey, hattın çok uzun olmasıdır. gist.github.com/milleniumbug/cf9b62cac32a07899378feef6c06c776 nasıl yeniden biçimlendireceğimi gösteriyor.
milleniumbug

1

Böyle bir tekniğin hata ayıklama gereği ile haklı çıkabileceğini sanmıyorum. Bu yaklaşıma bin kere rastladım ve zaman zaman bunu yapmaya devam ediyorum, ancak Martin Fowler'ın hata ayıklama hakkında söylediklerini hep aklımda tutuyorum :

İnsanlar ayrıca hata ayıklama için harcadıkları zamanı hafife alırlar. Uzun bir böceğin peşinde ne kadar zaman geçirebileceklerini hafife alıyorlar. Test yaparken, bir hata eklediğimde hemen anlarım. Bu, hemen taramaya ve gizlemeye başlamadan önce hatayı düzeltmeme izin veriyor. Hata ayıklamadan daha sinir bozucu veya zaman kaybı olan çok az şey vardır. İlk etapta böcekleri yaratmasaydık, çok daha hızlı olmaz mıydı?


Martin Fowler akıllı bir adam ve onun görüşlerini okumaktan zevk aldım. Testlerin gerekli olduğuna ve bu çaba için daha fazla zaman harcanması gerektiğine inanırken, hepimizin yanılabilir insanları olduğumuz gerçeği, hiçbir testin tüm hataları ortadan kaldırmayacağını göstermektedir . Bu nedenle, hata ayıklama her zaman program geliştirme ve destek sürecinin bir parçası olacaktır.
tale852150,

1

Bence bazı insanlar üçlü operatör gibi soruna somut olan meselelere asılıyorlar. Evet, birçok insan ondan nefret ediyor, bu yüzden yine de ortaya çıkması iyi olabilir.

Sorunuzun odak noktasıyla ilgili olarak, döndürülen ifadeyi bir değişken tarafından başvuruda bulunmak üzere dışarı çıkarmak

Bu soru aynı fikirde olmadığım 2 varsayımda bulunuyor:

  1. İkinci değişkenin okunması daha açık veya kolaydır (tersinin doğru olduğunu söylüyorum) ve

  2. herkesin Visual Studio'yu kullandığı. Visual Studio'yu birçok kez kullandım ve kullanabiliyorum, ama genellikle başka bir şey kullanıyorum. Belirli bir IDE'yi zorlayan dev bir ortam, şüpheci olacağım ortamdır.

Adlandırılmış bir değişkene bir şeyi dağıtmak nadiren hiç bir şeyi okumayı zorlaştırır, neredeyse her zaman bunun tersini yapar. Birinin bunu yaptığı belirli bir şekilde , kendi kendini belgeleyici bir liderin aşması, var thisVariableIsTheFormattedResultAndWillBeTheReturnValue = ...o zaman açıkça kötüdür, ama bu ayrı bir sorundur. var formattedText = ...iyidir.

Bu özel durumda ve muhtemelen 1 linerden bahsettiğimizden beri çoğu durumda, değişken, işlev adının zaten size söylemediği bir şey söylemez. Bu nedenle, değişken kadar eklemez. Hata ayıklama argümanı hala geçerli olabilir, ancak yine, bu özel durumda, hata ayıklama sırasında odak noktanız olabilecek bir şey göremiyorum ve daha sonra bir şekilde hata ayıklama için başka bir biçime veya başka bir şeye ihtiyaç duyması durumunda, her zaman kolayca değiştirilebilir.

Genel olarak, genel kuralı istemiştiniz (örneğin sadece genelleştirilmiş bir form örneği idi), varyant 1 (2-liner) lehine yapılan tüm noktalar doğrudur. Bunlar sahip olmak için iyi kurallar. Ancak kuralların esnek olması gerekir. Örneğin, üzerinde çalıştığım proje şu anda en fazla satır başına 80 karaktere sahip, bu yüzden çok fazla satır böldüm, ancak genel olarak okunabilirliği bölmek veya azaltmak için zor olacak 81-85 karakter satırları buluyorum ve bunları bırakıyorum limit.

Değer katma olasılığı düşük olduğundan, verilen belirli örnek için 2 satır yapmazdım. Ben varyant 2 (1-liner) yapardım çünkü bu durumda puanlar aksi takdirde yapacak kadar güçlü değil.

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.