Bir yöntemin false döndürüp döndürmediğini kontrol etme: sonucu geçici değişkene atama veya yöntem çağırma işlemini doğrudan koşullu hale getirme?


9

Bir if ifadesinde doğru veya yanlış değerler döndüren bir yöntemi çağırmak iyi bir uygulama mudur?

Bunun gibi bir şey:

private void VerifyAccount()
{
    if (!ValidateCredentials(txtUser.Text, txtPassword.Text))
    {
        MessageBox.Show("Invalid user name or password");
    }
}

private bool ValidateCredentials(string userName, string password)
{
    string existingPassword = GetUserPassword(userName);
    if (existingPassword == null)
        return false;

    var hasher = new Hasher { SaltSize = 16 };
    bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword);

    return passwordsMatch;
}

ya da bunları bir değişkende saklamak ve daha sonra böyle değerler kullanarak karşılaştırmak daha mı iyidir?

bool validate = ValidateCredentials(txtUser.Text, txtPassword.Text);
if(validate == false){
    //Do something
}

Sadece .NET'e atıfta bulunmuyorum, tüm programlama dillerindeki soruya atıfta bulunuyorum, bu yüzden .NET'i örnek olarak kullandım


3
Geçici bir değişken kullanıyorsanız, yazmak if (!validate)yerine yazın if (validate == false).
Philip

12
Ben bunu bir bool ama aksi evet onun iyi uygulamaların döndürmesi gereken bilmeleri ") CredentialsAreValid (" gibi işlev bir isim olur
Zachary K

3
IsValidCredentials, dilbilgisi açısından garip olsa da, bir boole dönüş değerini göstermek için yaygın bir biçimdir.
zzzzBov

@Philip if (! Validate) ile bu if (validate) arasındaki fark nedir ??
KyelJmD

!"NOT" operatörü ise, herhangi bir boole ifadesini reddeder. Bunun if (!validate)tam tersi if (validate). validateDoğru değilse if ifadesi girilir .
Philip

Yanıtlar:


26

Bütün bu şeylerde olduğu gibi duruma bağlıdır.

İçin yaptığınız çağrının sonucunu kullanmayacaksanız, sonucu ValidateCredentialsyerel bir değişkende saklamanıza gerek yoktur (hata ayıklama amaçları dışında). Ancak, bir değişkenin bu kodla gitmesi daha okunabilir (ve dolayısıyla daha sürdürülebilir) hale gelirse.

Kod ölçülebilir derecede daha az verimli olmayacaktır.


1
bu tür okunabilir mi? yukarıda yaptığım gibi
KyelJmD

@KyelJmD: Bu, programladığınız kültüre bağlıdır. Programladığım yerlerde !ValidateCredentials, daha okunabilir çünkü kodda ne yaptığını açıkça söylüyor. Çok açık. Aradığınız işlevin "kendi kendini belgeleyen" bir adı yoksa, değişkenle gitmek daha iyi olabilir. Durduğu gibi, değişkeni atlamayı ve sahip olduğunuz kendi kendini belgeleyen kodla kalmanızı tavsiye ederim.
Joel Etherton

ValidateCredentials ilk etapta okunamıyor - isim size sonucun ne anlama geldiğini nasıl anlatıyor? CredentialsAreValid veya CredentialsAreInvalid çok daha iyi.
gnasher729

9

Neden ek bir değişken kullanılmalı? İlk yaklaşımı kullanmayı tercih ederim, daha okunabilir ve basit.


4

Bir if ifadesinde doğru veya yanlış değerler döndüren bir yöntemi çağırmak iyi bir uygulama mudur?

Evet, koşullu satır içi ve okunabilir olacak kadar basit değilse.

ya da bunları bir değişkende saklamak ve daha sonra böyle değerler kullanarak karşılaştırmak daha mı iyidir?

Bunu yalnızca değeri birden çok yerde kullanıyorsanız veya kodu daha okunabilir hale getirmeniz gerekiyorsa yapmalısınız. Aksi takdirde, bir değişkene atama gerekli değildir. Gereksiz kod en iyi israftır ve en kötü ihtimalle bir kusur kaynağıdır.


2

Hadi görelim...

Her şey KISS ile ilgili olduğu için, onsuz yapabileceğinizde ek bir değişken oluşturmanıza gerek yoktur. Ayrıca, daha fazla yazmaya gerek yok ... ihtiyaç olmadığında.

Ama sonra KURU çünkü , daha sonra arar ValidateCredentialsve kendinizi yazarken ValidateCredentials(txtUser.Text, txtPassword.Text)bulursanız, ek bir değişken yaratmış gerektiğini biliyorsunuz.


2

Evet, şartlar gibi yöntemleri kullanmak genellikle iyidir. Ancak yöntem adı, yöntemin bir bool döndürdüğünü gösteriyorsa yararlıdır; örneğin CanValidateCredentials. C stili dillerde bu yöntem genellikle Is ve Can önekleri biçimindedir ve Ruby'de '?' soneki.


1
Yöntem adları hakkında iyi bir nokta, ama asla "if" ile bir yöntem adı başlatmak olmaz. Sonra kod "if" yazar. "Can" Tamam: if (cat.canOpenCanOfCatFood()).
kevin cline

Teşekkürler @ Kevin. "Değil" demek istemiştim. Cevabı düzenledim
Christian Horsdal

1

Henüz belirtilmeyen başka bir endişe daha var: kısa devre değerlendirmesi . Bu iki kod parçası arasındaki fark nedir?

Örn 1:

if(foo() && bar() && baz())
{
    quz();
}

Örn 2:

bool isFoo = foo();
bool isBar = bar();
bool isBaz = baz();
if(isFoo && isBar && isBaz)
{
    quz();
}

Bu iki kod parçası aynı şeyi yapıyor gibi görünüyor, ancak diliniz kısa devre değerlendirmesini destekliyorsa, bu iki parça farklıdır. Kısa devre değerlendirmesi, kodun bir koşulu geçmesi veya başarısız olması için gereken minimum değeri değerlendireceği anlamına gelir. Örnek 1 ise, foo () yanlış döndürürse, bar () ve baz () bile değerlendirilmez. Baz () uzun süren bir işlev çağrısıysa yararlıdır, çünkü foo () öğesi false değerini döndürürse veya foo () öğesi true değerini ve bar () false değerini döndürürse atlayabilirsiniz.

Örnek 2'de durum böyle değil. foo (), bar () ve baz () her zaman değerlendirilir. Bar () ve baz () öğelerinin yan etkiler sergilemesini bekliyorsanız, Örnek 1 ile ilgili sorunlarınız olacaktır. Yukarıdaki örnek # 1 aslında buna eşdeğerdir:

Eski 3:

if(foo())
{
    if(bar())
    {
        if(baz())
        {
            quz();
        }
    }
}

Örnekler 1 ve # 2 arasında seçim yaparken kodunuzdaki bu farklılıkların farkında olun.


1

Okunabilirlik sorunu biraz genişliyor ...

Sonucu bir değişkende saklamak için iki iyi neden düşünebilirim:

  1. Koşulu bir kereden fazla kullanacaksanız, değişkene kaydetmek işlevi yalnızca bir kez çağırmanız gerektiği anlamına gelir. (Bu, saklanan değerin hala geçerli olduğunu varsayar; tekrar test etmeniz gerekiyorsa, elbette bu geçerli değildir.)

  2. Bir değişkeni depolamak, koşula işlev çağrısında gördüğünüzden daha anlamlı bir ad vererek okunabilirliği artırır.

Örneğin, bu:

bool foo_is_ok = is_ok(foo);
if (foo_is_ok) ...

okunabilirliğe yardımcı olmaz, ancak bu:

bool done_processing = feof(file1) && feof(file2);
if (done_processing) ...

Muhtemelen öyle, çünkü bu açıkça feof(file1) && feof(file2)işlendiğimiz anlamına geliyor.

Söz konusu passwordsMatchdeğişken muhtemelen benimkinden daha iyi bir örnektir.

Tek kullanımlık değişkenler, bir değere anlamlı bir ad verirlerse yararlıdır. (Bu elbette insan okuyucunun yararınadır.)


Sanırım, done_processingdeğişkeni tanıtmak yerine bir yorum bırakmak istiyorum . Sonuçta, ad done_processingbir yorumun işlevini sunar. Ve gerçek bir yorum, bu durumun neden işlemeyle bittiğimizi gösteren bir veya iki kelime söylememe izin veriyor . Ben büyük bir yorumcu değilim, ama, muhtemelen gerçek kodda ne
yapardım

@cmaster: Yorumlarla ilgili bir sorun, kodla senkronizasyondan kolayca kurtulabilmeleridir. Adlı bir değişken done_processing, amacı ifade etmenin daha dayanıklı bir yoludur.
Keith Thompson

2 numaralı nokta için +1 - bazen iyi adlandırılmış bir temp var şeyleri gerçekten netleştirir.
user949300
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.