ReSharper Curiosity: "Parametre yalnızca ön koşul kontrolleri için kullanılır."


103

ReSharper neden beni bu kod için yargılıyor?

    private Control GetCorrespondingInputControl(SupportedType supportedType, object settingValue)
    {
        this.ValidateCorrespondingValueType(supportedType, settingValue);

        switch(supportedType)
        {
            case SupportedType.String:
                return new TextBox { Text = (string)settingValue };
            case SupportedType.DateTime:
                return new MonthPicker { Value = (DateTime)settingValue, ShowUpDown = true };
            default:
                throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding user control defined.", supportedType));
        }
    }

    private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
    {
        Type type;

        switch(supportedType)
        {
            case SupportedType.String:
                type = typeof(string);
                break;
            case SupportedType.DateTime:
                type = typeof(DateTime);
                break;
            default:
                throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding Type defined.", supportedType));
        }
        string exceptionMessage = string.Format("The specified setting value is not assignable to the supported type, [{0}].", supportedType);
        if(settingValue.GetType() != type)
        {
            throw new InvalidOperationException(exceptionMessage);
        }
    }

İkinci yöntem ValidateCorrespondingValueType'ın "settingValue" parametresi, ReSharper tarafından aşağıdaki mesajla griye çevrilir: "Parametre 'settingValue' yalnızca ön koşul kontrol (ler) i için kullanılır."


Sen ilanını ve atama taşıyabilirsiniz exceptionMessageiçine if:) -bloku
AakashM

Bunu şu yöntemde de yapabilirsiniz: beklenenText + = ""; ve yöntemde kullandığınız için şikayet etmeyi bırakır.
PHPGuru

Yanıtlar:


104

Yargılamak değil, yardım etmeye çalışıyor :)

ReSharper bir parametrenin yalnızca bir istisna atmak için bir kontrol olarak kullanıldığını görürse, onu grileştirerek onu "gerçek" iş için kullanmadığınızı gösterir. Bu büyük olasılıkla bir hatadır - neden kullanmayacağınız bir parametreyi iletesiniz? Genellikle bunu bir ön koşulda kullandığınızı, ancak daha sonra kodun başka bir yerinde kullanmayı unuttuğunuzu (veya artık gerekmediğini) gösterir.

Yöntem bir onaylama yöntemi olduğundan (yani, tek yaptığı geçerli olduğunu iddia etmektir), ValidateCorrespondingValueTypeReSharper'ın ek açıklama niteliklerini , özellikle de [AssertionMethod]özniteliği kullanarak, bir onaylama yöntemi olarak işaretleyerek mesajı bastırabilirsiniz :

[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
  // …
}

3
Bu güzel bir çek, ancak bu durumda R # biraz aşıldı, değil mi? Yöntemin gövdesi içinde bazı işler yapılana kadar, karşı kontrol edildiği şey bilinmediği için settingValuetürünün kontrolü bir ön koşul olamaz!
AakashM

6
Bu yüzden ReSharper'a bunun bir iddia yöntemi olduğunu söylemelisiniz. Bu yöntemin tek amacı, başka bir yöntem için ön koşul kontrolünü gerçekleştirmektir. Bu bir iddia, ancak ReSharper siz söylemedikçe bunu bilemez [AssertionMethod].
Citizenmatt

10
Sonunda İnceleme Önem Derecesini "Gösterme" olarak değiştirdim, bu başka bir seçenek.
reggaeguitar

61
Normal kullanılmayan parametre incelemesinden bağımsız olarak 'yalnızca ön koşul' denetimi devre dışı bırakılabilseydi, bu yararlı bir özellik olabilirdi; halihazırda denetim, farklı önem derecelerine sahip iki konuyu karıştırır ve genellikle bu işlevselliği belirli durumlarda işe yaramaz hale getirir. Ayrıca, sadece bir kaynak kodu analiz aracını mutlu etmek için koda yorum veya nitelik ekleme fikrine çok kuşkuluyum, bu yüzden şu anda soruna tatmin edici bir çözüm olduğunu düşünmüyorum.
Serge Belov

7
Yardım etmeye çalışıyor olabilir ama çok agresif. Şimdi, değeri doğrular ve sonra onu asla kullanmazsanız, iyi, bu muhtemelen bir hata. Ancak, yalnızca hatadaki değeri kullandığım bir yerde bana havlıyor. Kasıtlı olmaktan başka nasıl bir şey olabilir ki?
Loren Pechtel

21

İlginç bir şekilde, ReSharper nameof, C # 6'daki yeni işlevi kullanırsanız geri adım atıyor :

static void CheckForNullParameters(IExecutor executor, ILogger logger)
{
    if (executor == null)
    {
        throw new ArgumentNullException(nameof(executor));
    }

    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }
}

3
bu cevap bana uyuyor, nuget paketi eklemekten daha az müdahaleci
DanielV

8

Aşağıdakiler sorunu düzeltir (ReSharper 2016.1.1, VS2015'te), ancak 'doğru' sorunu çözdüğünden emin değilim. Her durumda, bu konuyla ilgili ReSharper'ın mekaniğindeki belirsizliği gösterir:

Bu şu uyarıyı verir:

    private void CheckForNull(object obj)
    {
        if (ReferenceEquals(obj, null))
        {
            throw new Exception();
        }
    }

Ancak bu:

    private void CheckForNull(object obj)
    {
        if (!ReferenceEquals(obj, null))
        {
            return;
        }
        throw new Exception();
    }

Eşdeğer kodun (tersine çevirme ReSharper tarafından yapıldı: D) farklı sonuçlar vermesi ilginçtir. Öyle görünüyor ki desen eşleştirme ikinci versiyonu almıyor.


6

Bu sorunun My tercih edilen çözüm parametre düşünüyorum resharper yapmak olduğunu edilir kullandı. Bunun, bir özniteliği kullanmaya göre bir avantajı vardır, UsedImplicitlyçünkü bunu yaparsanız durdurma o parametresini kullanarak, resharper tekrar uyarı başlayacaktır. Bir öznitelik kullanırsanız, yeniden paylaşım da gelecekteki gerçek uyarıları yakalamaz.

Yeniden paylaşımcıya parametrenin kullanıldığını düşünmesini sağlamanın kolay bir yolu throw, bir yöntemle değiştirmektir . Yani bunun yerine ...

if(myPreconditionParam == wrong)
    throw new Exception(...);

...Sen yaz:

if(myPreconditionParam == wrong)
    new Exception(...).ThrowPreconditionViolation();

Bu, gelecekteki programcılar için güzel bir şekilde kendi kendini belgeliyor ve yeniden paylaşımcı sızlanmayı bırakıyor.

ThrowPreconditionViolation'ın uygulanması önemsizdir:

public static class WorkAroundResharperBugs 
{
    //NOT [Pure] so resharper shuts up; the aim of this method is to make resharper 
    //shut up about "Parameter 'Foobaar' is used only for precondition checks" 
    //optionally: [DebuggerHidden]
    public static void ThrowPreconditionViolation(this Exception e)
    {
        throw e;
    }
}

İstisna üzerinde bir uzantısı yöntemi olan ad kirliliği, ama oldukça içerdiği oluyor.


+1 [UsedImplicitly], öyle olmadığı [AssertionMethod]gibi kullanmak istemedim ve benim durumumda örtük olarak kullandım (bir yapıcıdaki geri aramaya bir değer iletiyor ve oluşturulan nesneyi döndürüyordum).
MrLore

1

Diğerleri soruyu zaten cevapladı, ancak kimse uyarıyı kapatmak için aşağıdaki yollardan bahsetmedi.

Bunu, yalnızca bu yöntem için kapatmak üzere yöntem imzasının üzerine ekleyin:

    // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local

Tüm dosya için kapatmak için bunu sınıf bildiriminin üzerine ekleyin:

     // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local

Bir dezavantaj, demek istediğiniz cadı parametresini belirtememenizdir.
comecme

1
@comecme Belirli bir parametrenin etrafındaki açıklamaları devre dışı bırakma ve geri yükleme özelliğini kullanarak tek bir parametre için devre dışı bırakabilirsiniz . Bu durumda her parametreyi kendi satırına koymanızı öneririm; hala çirkin ama daha az (bence).
Travis
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.