Reshaper表示??
的左侧永远不会为空,即使其类型为int?
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
自动重构“删除无法访问的代码”将其转换为:
_savedMediaFileId = (int) mediaFile.MediaFileId;
这是对的还是Resharper在这里犯了错误?
我的想法是因为int?可以为空,那么我可以使用??保留现有值,如果它为null。
这是我的单元测试(正在进行中)
[TestClass]
public class MediaRepositoryTest
{
private const string SiteId = "3";
private const string ConnectionString =
@"Data Source=dvmind\mssqlsites;Database=***********;User Name=sa;Password=**************";
private string _mediaSourceName = "TestMediaSourceName";
private string _mediaTypeName = "TestMediaTypeName";
private string _mediaSourceAddress = "TestMediaSourceAddress";
private string _mediaFileAddress = "TestMediaFileAddress";
private int _savedMediaFileId = 0;
private string GetGuidString()
{
return Convert.ToBase64String(Guid.NewGuid().ToByteArray());
}
[TestInitialize]
public void TestInitialize()
{
_mediaSourceName = _mediaSourceName + GetGuidString();
_mediaTypeName = _mediaTypeName + GetGuidString();
_mediaSourceAddress = _mediaSourceAddress + GetGuidString();
_mediaFileAddress = _mediaFileAddress + GetGuidString();
}
[TestCleanup]
public void TestCleanup()
{
using (var db = new SiteContext(ConnectionString))
{
if (_savedMediaFileId != 0)
{
(from c in db.MediaFiles where c.MediaFileId == _savedMediaFileId select c).ToList()
.ForEach(c => db.MediaFiles.Remove(c));
}
(from c in db.MediaSources where c.MediaSourceName == _mediaSourceName select c).ToList()
.ForEach(c => db.MediaSources.Remove(c));
(from c in db.MediaTypes where c.MediaTypeName == _mediaTypeName select c).ToList()
.ForEach(c => db.MediaTypes.Remove(c));
}
}
[TestMethod]
public void SaveMediaTest()
{
var mediaSource = new MediaSource
{
MediaSourceName = _mediaSourceName,
MediaSourceAddress = _mediaSourceAddress
};
var mediaType = new MediaType
{
MediaTypeName = _mediaTypeName
};
var mediaFile = new MediaFile
{
SiteId = SiteId,
MediaFileAddress = _mediaFileAddress,
MediaSource = mediaSource,
MediaType = mediaType
};
var connectionStringProvider =
Mock.Of<IConnectionStringProvider>(c => c.GetConnectionString() == ConnectionString);
var repository = new MediaRepository(connectionStringProvider);
Assert.IsTrue(mediaFile.MediaFileId == 0);
repository.SaveMedia(mediaFile);
Assert.IsTrue(mediaFile.MediaFileId != 0);
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
//using (var db = new SiteContext(ConnectionString))
//{
//}
}
答案 0 :(得分:3)
现在您已经发布了一个完整的示例,我认为您获得无法访问的代码的原因是由于此行之前的Assert条件;
Assert.IsTrue(mediaFile.MediaFileId == 0);
如果mediaFile.MediaFileId为null,程序退出此行,如果不是,则警告正确; mediaFile.MediaFileId在您突出显示的行上不能为空;
_savedMediaFileId = mediaFile.MediaFileId ?? _savedMediaFileId;
此外,如果SaveMedia
的定义采用了ref MediaFile
也会影响警告,因为可能(就ReSharper而言)该值再次更改为Null by ;
repository.SaveMedia(mediaFile);
这些更改都会影响警告的存在。
答案 1 :(得分:2)
ReSharper可能会在此推断mediaFile.MediaFileId
永远不会有值null
,即使类型为int?
。因此,它建议您完全跳过null
检查并直接获取值
更清晰的例子是以下
string s = "hello world";
if (s != null) {
...
}
在这种情况下,s
实际上可能是null
,因为它属于string
类型而null
是有效值。但是在此特定上下文中s
永远不会是null
因此ReSharper会将此检查标记为不必要
答案 2 :(得分:0)
这是一个猜测,但我认为这里发生了什么(基于MSDN
当你声明某些int?时,它不会创建一个可以为null的引用类型。相反,它会创建Nullable<T>
,这是struct
,意味着它不能为空b / c它是值类型。除了值之外的那个结构包含一个布尔标志,告诉它是否为null,如果值有效。
因此,做int? ??
本质上是测试一个结构为空值,它永远不会。它不测试Nullable<T>.HasValue
哪种方法可以测试是否为“null”。
因此ReSharper投诉。