¿Por qué ReSharper me juzga por este código?
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);
}
}
El parámetro "settingValue" del segundo método ValidateCorrespondingValueType está atenuado con el siguiente mensaje de ReSharper: "El parámetro 'settingValue' solo se usa para verificaciones de condiciones previas".
c#
resharper
preconditions
Corpsekicker
fuente
fuente
exceptionMessage
en elif
bloque :)Respuestas:
No está juzgando, está tratando de ayudar :)
Si ReSharper ve que un parámetro solo se usa como verificación para lanzar una excepción, lo atenúa, lo que indica que en realidad no lo está usando para un trabajo "real". Lo más probable es que se trate de un error: ¿por qué pasar un parámetro que no va a utilizar? Por lo general, indica que lo usó en una condición previa, pero luego olvidó (o ya no necesita) usarlo en otra parte del código.
Dado que el método es un método de aserción (es decir, todo lo que hace es afirmar que es válido), puede suprimir el mensaje marcando
ValidateCorrespondingValueType
como un método de aserción, utilizando los atributos de anotación de ReSharper , específicamente el[AssertionMethod]
atributo:fuente
settingValue
no puede ser una condición previa , ya que la cosa contra la que se está verificando no se conoce hasta que se haya realizado algún trabajo dentro del cuerpo del método.[AssertionMethod]
.Curiosamente, ReSharper retrocede si usa la nueva
nameof
funcionalidad en C # 6:fuente
Lo siguiente soluciona el problema (en ReSharper 2016.1.1, VS2015), pero no estoy seguro de que resuelva el problema "correcto". En cualquier caso, muestra la ambigüedad en la mecánica de ReSharper con respecto a este tema:
Esto produce la advertencia:
Pero esto no:
Es interesante que el código equivalente (la inversión fue realizada por ReSharper: D) da resultados diferentes. Parece que la coincidencia de patrones simplemente no recoge la segunda versión.
fuente
Mi solución preferida a este problema es hacer que el resharper piense que se usa el parámetro . Esto tiene una ventaja sobre el uso de un atributo, como
UsedImplicitly
porque si alguna vez qué dejar de usar ese parámetro, ReSharper se iniciará un aviso de nuevo. Si usa un atributo, el resharper tampoco detectará advertencias reales futuras.Una forma sencilla de hacer que el afilado piense que se utiliza el parámetro es sustituyéndolo
throw
por un método. Entonces en lugar de ......usted escribe:
Esto es muy bien autodocumentado para futuros programadores, y el resharper deja de quejarse.
La implementación de ThrowPreconditionViolation es trivial:
Un método de extensión en Exception es la contaminación del espacio de nombres, pero está bastante contenido.
fuente
[UsedImplicitly]
, no quería usarlo[AssertionMethod]
ya que no lo era, y el uso implícito suena más preciso en mi caso (estaba pasando un valor a una devolución de llamada en un constructor y devolviendo el objeto construido).Otros ya han respondido a la pregunta, pero nadie mencionó las siguientes formas de desactivar la advertencia.
Agregue esto encima de la firma del método para desactivarlo solo para ese método:
Agregue esto encima de la declaración de clase para desactivarlo para todo el archivo:
fuente