You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:22:28