为何ReSharper 2024.2不推荐使用ArgumentNullException.ThrowIfNullOrEmpty?
ReSharper 2024.2参数校验建议与异常类型冲突问题
我在使用ReSharper 2024.2时,它提示我替换以下参数校验代码:
原代码:
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse { ArgumentNullException.ThrowIfNullOrEmpty(query); ArgumentNullException.ThrowIfNullOrWhiteSpace(query); ArgumentNullException.ThrowIfNull(Logger);
ReSharper推荐的第一种写法:
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse { ArgumentException.ThrowIfNullOrEmpty(query); ArgumentException.ThrowIfNullOrWhiteSpace(query); ArgumentNullException.ThrowIfNull(Logger);
第二种推荐写法:
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse { if (string.IsNullOrEmpty(query) || string.IsNullOrWhiteSpace(query)) throw new ArgumentNullException(nameof(query));
核心问题
按照ReSharper的建议使用ArgumentException.ThrowIfNullOrEmpty()或ArgumentException.ThrowIfNullOrWhiteSpace()时,抛出的异常是ArgumentException,但我预期的是ArgumentNullException,这直接导致相关单元测试失败。
测试案例验证
以下测试代码可复现该问题:
[TestFixture] public class Tests { readonly MyClass _testClass = new(); #region 传入Null时抛出ArgumentNullException,测试通过 [Test] public void Test_MyMethod_Passes() { Assert.Throws<ArgumentNullException>(() => { _ = _testClass.Method(null); // 抛出ArgumentNullException,测试通过 }); } [Test] public void Test_MyMethodAsync_Passes() { Assert.ThrowsAsync<ArgumentNullException>(async () => await _testClass.MethodAsync(null).ToListAsync()); // 抛出ArgumentNullException,测试通过 } #endregion #region 返回ArgumentException而非ArgumentNullException,测试失败 [TestCase("")] [TestCase(" ")] public void Test_MyMethod(string someText) { Assert.Throws<ArgumentNullException>(() => _testClass.Method(someText)); // 抛出ArgumentException,测试失败 } [TestCase("")] [TestCase(" ")] public void Test_MyMethodAsync_Fails(string someText) { Assert.ThrowsAsync<ArgumentNullException>(async () => await _testClass.MethodAsync(someText).ToListAsync()); // 抛出ArgumentException,测试失败 } #endregion } public class MyClass { public List<string> Method(string? someText) { ArgumentNullException.ThrowIfNull(someText); ArgumentException.ThrowIfNullOrEmpty(someText); ArgumentException.ThrowIfNullOrWhiteSpace(someText); var result = new List<string> { "Document1", "Document2" }; return result; } public async IAsyncEnumerable<string> MethodAsync(string? someText) { ArgumentNullException.ThrowIfNull(someText); ArgumentException.ThrowIfNullOrEmpty(someText); ArgumentException.ThrowIfNullOrWhiteSpace(someText); // 模拟异步数据获取 await Task.Delay(100); yield return "Document1"; yield return "Document2"; } }
结论
若要确保抛出ArgumentNullException,必须使用ArgumentNullException.ThrowIfNullOrEmpty(someText)方法,而非ReSharper推荐的ArgumentException类下的对应方法,否则会得到ArgumentException异常,不符合预期。
内容的提问来源于stack exchange,提问作者csharpforevermore
相关产品推荐
相关产品推荐

