如何消除C#空引用警告CS8604?已做空值检查仍触发警告
解决CS8604警告:cachedData可能为空的问题
编译器警告CS8604是因为静态分析无法识别RedisValue的HasValue和IsNullOrEmpty检查能确保它作为字符串参数时非空。以下几种方法可以消除警告:
方法1:使用!空值抑制运算符
直接在cachedData后添加!,明确告诉编译器该值不会为空:
string cacheKey = "Test1"; RedisValue cachedData = await cache.StringGetAsync(cacheKey); if (cachedData.HasValue && !cachedData.IsNullOrEmpty) { // 添加!运算符消除警告 IList<Model1>? result = JsonConvert.DeserializeObject<IList<Model1>>(cachedData!); if (result != null) { data = result; return data; } } data = await repo.GetModel1(); await cache.StringSetAsync(cacheKey, JsonConvert.SerializeObject(data), TimeSpan.FromMinutes(5)); return data;
方法2:转换为字符串并显式检查
将RedisValue转换为string类型,再做非空检查,编译器能识别这类常规空值判断:
string cacheKey = "Test1"; RedisValue cachedData = await cache.StringGetAsync(cacheKey); string? cacheString = cachedData.ToString(); if (!string.IsNullOrEmpty(cacheString)) { IList<Model1>? result = JsonConvert.DeserializeObject<IList<Model1>>(cacheString); if (result != null) { data = result; return data; } } data = await repo.GetModel1(); await cache.StringSetAsync(cacheKey, JsonConvert.SerializeObject(data), TimeSpan.FromMinutes(5)); return data;
方法3:使用模式匹配获取非空值
利用C#的模式匹配直接提取非空的字符串变量,无需额外空值检查:
string cacheKey = "Test1"; RedisValue cachedData = await cache.StringGetAsync(cacheKey); // 模式匹配,只有cachedData能转换为非空string时才进入分支 if (cachedData is string nonNullCacheData) { IList<Model1>? result = JsonConvert.DeserializeObject<IList<Model1>>(nonNullCacheData); if (result != null) { data = result; return data; } } data = await repo.GetModel1(); await cache.StringSetAsync(cacheKey, JsonConvert.SerializeObject(data), TimeSpan.FromMinutes(5)); return data;
为什么原代码的检查无效?
RedisValue是值类型,它的HasValue和IsNullOrEmpty属于自定义属性检查,C#的静态分析器无法自动关联这些检查与后续参数的非空性,所以需要通过上述方式明确告知编译器值的非空状态。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

