从缓存中获取对象时,代码是启发式无法访问的

Lui*_*cia 2 c# resharper fxcop

我有以下代码,如果对象在缓存中获取它的想法很简单,如果没有然后从数据源检索它并将其保存到缓存中,我使用resharper我得到了这个警告但是无法理解为什么

 public static ModulosPorUsuario GetModulesForUser(string identityname)
        {
            // It needs to be cached for every user because every user can have different modules enabled.
            var cachekeyname = "ApplicationModulesPerUser|" + identityname;

            var cache = CacheConnectionHelper.Connection.GetDatabase();
            ModulosPorUsuario modulosUsuario;

            //get object from cache
            string modulosUsuariosString = cache.StringGet(cachekeyname);

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if (modulosUsuariosString != null)
            {
                //conver string to our object
                modulosUsuario = JsonConvert.DeserializeObject<ModulosPorUsuario>(modulosUsuariosString);
                return modulosUsuario;
            }
            // ReSharper disable once HeuristicUnreachableCode
            modulosUsuario = DbApp.ModulosPorUsuario.Where(p => p.Email == identityname).FirstOrDefault();

            //convert object to json string
            modulosUsuariosString = JsonConvert.SerializeObject(modulosUsuario);

            //save string in cache
            cache.StringSet(cachekeyname, modulosUsuariosString, TimeSpan.FromMinutes(SettingsHelper.CacheModuleNames));
            return modulosUsuario;
        }
Run Code Online (Sandbox Code Playgroud)

Iga*_*nik 5

这里有相当多的内容,但最重要的是,这是一个ReSharper错误 - 值肯定是空的,我有一个更小的例子来证明它.

首先,让我们弄清楚代码中发生了什么.我不得不深入挖掘StackExchange.Redis您正在使用的库.cache事实上,你的对象是一个IDatabaseRedisDatabase类实现的对象.StringGet您正在使用的方法返回a RedisValue,这是一个结构.这本身就足以说明为什么ReSharper告诉你它永远不会是null - 值类型不能!

但是,您将结果放入string变量中!这是有效的,因为RedisValuestruct定义了一堆隐式运算符来将值转换为请求的类型.如果是字符串,请注意如果blob为空,则返回空字符串:

RedisValue.cs

/// <summary>
/// Converts the value to a String
/// </summary>
public static implicit operator string(RedisValue value)
{
    var valueBlob = value.valueBlob;
    if (valueBlob == IntegerSentinel)
        return Format.ToString(value.valueInt64);
    if (valueBlob == null) return null;

    if (valueBlob.Length == 0) return "";
    try
    {
        return Encoding.UTF8.GetString(valueBlob);
    }
    catch
    {
        return BitConverter.ToString(valueBlob);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是从这段代码中可以看出字符串null也是如此.

这使得ReSharper不正确地标记该行,并且可以使用较小的示例再现它:

static void Main(string[] args)
{
    string value = MyStruct.GetValue();
    if (value == null) // <- ReSharper complains here, but the value is null!
    {
        return;
    }
}

public struct MyStruct
{
    public static MyStruct GetValue() => new MyStruct();

    public static implicit operator string(MyStruct s)
    {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我向JetBrains 报告了这个问题,他们会修复它.

在此期间,您可能希望保留该注释,禁用ReSharper警告.