Dlaczego ReSharper ocenia mnie za ten kod?
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);
}
}
Parametr „settingValue” drugiej metody ValidateCorrespondingValueType jest wyszarzony z następującym komunikatem ReSharper: „Parametr„ settingValue ”jest używany tylko do sprawdzania warunków wstępnych."
c#
resharper
preconditions
Corpsekicker
źródło
źródło
exceptionMessage
doif
-bloku :)Odpowiedzi:
To nie ocenianie, tylko próba pomocy :)
Jeśli narzędzie ReSharper widzi, że parametr jest używany tylko jako sprawdzenie, aby zgłosić wyjątek, wyszarza go, wskazując, że w rzeczywistości nie używasz go do „prawdziwej” pracy. Najprawdopodobniej jest to błąd - po co przekazywać parametr, którego nie będziesz używać? Zwykle oznacza, że użyłeś go w stanie wstępnym, ale zapomniałeś (lub już nie potrzebujesz) użyć go w innym miejscu kodu.
Ponieważ metoda jest metodą asercji (to znaczy wszystko, co robi, to potwierdza, że jest prawidłowa), możesz pominąć komunikat, oznaczając
ValidateCorrespondingValueType
jako metodę potwierdzenia, używając atrybutów adnotacji ReSharper , w szczególności[AssertionMethod]
atrybutu:źródło
settingValue
nie może być warunkiem wstępnym, ponieważ rzecz, względem której jest sprawdzany, nie jest znana, dopóki nie zostanie wykonana pewna praca w treści metody![AssertionMethod]
.Co ciekawe, ReSharper wycofuje się, jeśli używasz nowej
nameof
funkcjonalności w C # 6:źródło
Poniższe rozwiązania rozwiązują problem (w ReSharper 2016.1.1, VS2015), ale nie jestem pewien, czy rozwiązuje „właściwy” problem. W każdym razie pokazuje to niejednoznaczność w mechanice ReSharpera w tym temacie:
Daje to ostrzeżenie:
Ale to nie:
Co ciekawe, równoważny kod (inwersję wykonał ReSharper: D) daje inne wyniki. Wydaje się, że dopasowanie wzorców po prostu nie odbiera drugiej wersji.
źródło
Moim preferowanym rozwiązaniem tego problemu jest przekonanie resharpera, że parametr jest używany. To ma przewagę nad użyciem atrybutu, takie jak
UsedImplicitly
, bo jeśli kiedykolwiek ma przystanek przy użyciu tego parametru resharper rozpocznie ostrzeżenia ponownie. Jeśli użyjesz atrybutu, reharper również nie złapie prawdziwych ostrzeżeń w przyszłości.Łatwym sposobem na przekonanie osoby, że parametr jest używany, jest zastąpienie
throw
go metodą. Więc zamiast ......ty piszesz:
Jest to przyjemne samodokumentowanie dla przyszłych programistów, a ponownie przestaje marudzić.
Implementacja ThrowPreconditionViolation jest trywialna:
Metoda rozszerzenia w Exception to zanieczyszczenie przestrzeni nazw, ale jest dość ograniczona.
źródło
[UsedImplicitly]
, nie chciałem używać,[AssertionMethod]
ponieważ nie było, i użyte domyślnie brzmi to dokładniej w moim przypadku (przekazywałem wartość do wywołania zwrotnego w konstruktorze i zwracałem skonstruowany obiekt).Inni już odpowiedzieli na pytanie, ale nikt nie wspomniał o następujących sposobach wyłączenia ostrzeżenia.
Dodaj to nad podpisem metody, aby wyłączyć ją tylko dla tej metody:
Dodaj to powyżej deklaracji klasy, aby wyłączyć ją dla całego pliku:
źródło