key
は、ResharperがNULLでないことを知っていなくても、key
の最後の2つの参照にResharperによってフラグが立てられます。Resharper - Nullを非nullに割り当てる可能性のある偽陽性の属性
最初に、Null、空または空白の文字列プロパティがチェックされ、これらの条件のいずれかが該当する場合、ブロックはスキップされます。拡張メソッドToLowerNullSafe()
は、入力がNULLの場合にのみNullを返します。これはAnnotation(2番目のコードブロック)でマークされます。プロパティがnullでなく、拡張メソッドがnull以外を返すようにマークされているので、Resharperはkey
がnullではないことを知っていると思います。
var myObj = new { MyProperty = "some string" };
var myCache = new Dictionary<string, object>();
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
key
のフラグが設定されている場合、上記これらの2行は次のとおりここ
if (!myCache.ContainsKey(key))
と
myCache.Add(key, myObj);
は、その注釈付きToLowerNullSafe方法、です。
[ContractAnnotation("null => null; notnull => notnull")]
public static string ToLowerNullSafe(this string str)
{
return string.IsNullOrWhiteSpace(str) ? str : str.ToLower();
}
ReSharperのは、注釈を無視しているように見える理由は上の任意のアイデア?そして私はそれをどのように修正するのですか?
使用:
- Visual Studioの究極の2013アップデート5
- ReSharperのNuget(コードおよび外部の両方)から8.2.3
- 現在の注釈は、プロジェクトに適用されます。
- 純4.5.2
EDIT
冗長ヌル!string.IsNullOrWhiteSpace
チェックがエラーをクリアする前または後のいずれかの冗長ヌルチェック(myObj.MyProperty != null
)を追加myObj.MyProperty
の確認。
if (myObj.MyProperty != null && !string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
冗長ヌル冗長チェック、アサーション、または契約の仮定を追加すると、エラーをクリアすることができますkey
に確認してください。
ここでは、key
に値を割り当てた直後にContract.Assume(key != null);
を追加しました。
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
Contract.Assume(key != null);
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
これもエラーをクリアしToLowerNullSafe
を呼び出すことはありません。しかし、ContainsKey
メソッドは大文字と小文字を区別しない比較を行う場合に大文字と小文字を区別した比較を実行するため、問題が発生する可能性があります。
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty;
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
は、組み込みの文字列関数ToLower
を呼び出すまた、これはエラーをクリアします。しかし、コードベースに矛盾が生じます。ヌル値が予想され、安全に処理されなければならないコードには多くの場所があります。問題を避けるために、コード全体でカスタム...NullSafe
拡張メソッドを適用しました。それが「ベストプラクティス」と一致するかどうかはわかりませんが、このプロジェクトで行っていることです。すべての作業のコード例では
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLower();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
、ReSharperのは、単にToLowerNullSafe
拡張メソッドに契約注釈を無視しているようです。しかし、最初の実例では、はであるが、オブジェクトのプロパティに対して明示的で冗長なヌルチェックを使用することによって認識されます。
これとは別に、大文字と小文字を区別するデフォルトの比較文字ではなく、大文字と小文字を区別しない文字列比較文字を使用して辞書を作成すると便利です。その後、「ToLower」に電話する必要はありません。 [このような質問はこちら]を参照してください。(http://stackoverflow.com/questions/13230414/case-insensitive-access-for-generic-dictionary) – citizenmatt
@citizenmatt私はその提案を調査する必要があります。 – Zarepheth