ReSharperがこのコードについて私を判断するのはなぜですか?
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);
}
}
2番目のメソッドValidateCorrespondingValueTypeの「settingValue」パラメーターは、ReSharperによって次のメッセージでグレー表示されます。「パラメーター 'settingValue'は前提条件チェックにのみ使用されます」。
それは判断ではなく、助けようとしている:)
パラメーターが例外をスローするためのチェックとしてのみ使用されることをReSharperが確認した場合、グレー表示され、「実際の」作業に実際に使用していないことを示します。これはおそらく間違いです-使用しないパラメーターを渡すのはなぜですか?通常、前提条件で使用したが、コードの他の場所で使用することを忘れた(または必要なくなった)ことを示します。
メソッドはアサーションメソッドなので(つまり、有効であるとアサートするだけです)、ReSharperの アノテーション属性 を使用して、ValidateCorrespondingValueType
をアサーションメソッドとしてマークすることにより、メッセージを抑制することができます。 、特に[AssertionMethod]
属性:
[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
// …
}
興味深いことに、C#6で新しいnameof
機能を使用すると、ReSharperは後退します。
static void CheckForNullParameters(IExecutor executor, ILogger logger)
{
if (executor == null)
{
throw new ArgumentNullException(nameof(executor));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
}
この問題に対する私の好ましい解決策は、resharperにパラメーターisが使用されていると考えさせることです。これには、UsedImplicitly
などの属性を使用するよりも利点があります。これは、doそのパラメーターの使用を停止すると、resharperが再び警告を開始するためです。属性を使用する場合、resharperは将来の実際の警告もキャッチしません。
再シャーパーにパラメーターが使用されていると思わせる簡単な方法は、throw
をメソッドに置き換えることです。代わりに...
if(myPreconditionParam == wrong)
throw new Exception(...);
...あなたが書く:
if(myPreconditionParam == wrong)
new Exception(...).ThrowPreconditionViolation();
これは将来のプログラマーのためにうまく自己文書化され、再シャーパーは泣き言をやめます。
ThrowPreconditionViolationの実装は簡単です。
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;
}
}
例外の拡張メソッドis名前空間汚染ですが、かなり含まれています。
以下は(ReSharper 2016.1.1、VS2015で)問題を修正しますが、「正しい」問題を解決するかどうかはわかりません。いずれにしても、このトピックに関するReSharperのメカニズムのあいまいさを示しています。
これにより、警告が生成されます。
private void CheckForNull(object obj)
{
if (ReferenceEquals(obj, null))
{
throw new Exception();
}
}
しかし、これはそうではありません:
private void CheckForNull(object obj)
{
if (!ReferenceEquals(obj, null))
{
return;
}
throw new Exception();
}
同等のコード(反転はReSharper:Dによって行われた)が異なる結果を与えることは興味深いです。パターンマッチングは、単に2番目のバージョンを選択しないようです。