扩展方法未按预期抛出异常

本文关键字:抛出异常 方法 扩展 | 更新日期: 2023-09-27 18:02:14

我有以下扩展方法:

public static T ToObject<T>(this DataRow row) where T : new()
{
    if (row == null) throw new ArgumentNullException("row");
    // do something
}
public static IEnumerable<T> ToObject<T>(this DataTable table) where T : new()
{
    if (table == null) throw new ArgumentNullException("table");
    // do something
}

和相应的测试:

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void NullDataRow()
{
    // Arrange
    DataRow row = null;
    // Act
    row.ToObject<SomeData>();
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void NullDataTable()
{
    // Arrange
    DataTable table = null;
    // Act
    table.ToObject<SomeData>();
}

DataRow测试通过(它正常抛出ArgumentNullException),而DataTable测试没有(不击中方法也不抛出任何东西)。

我完全不知道为什么DataTable测试不工作(DataRow测试是正常的!)。

(起初我认为这是我的Visual Studio中的一个错误,但我使用的CI服务指责相同)

扩展方法未按预期抛出异常

我假设IEnumerable<T>不仅仅是为了好玩,而且扩展方法实际上是一个迭代器。

这样的迭代器,直到你开始迭代它时才会抛出异常。

你在这里发布的代码不足以诊断问题,因为它是由隐藏在/// do something评论后面的东西引起的。查看github上的代码:

public static IEnumerable<T> ToObject<T>(this DataTable table) where T : new()
{
    if (table == null) throw new ArgumentNullException("table");
    foreach (DataRow row in table.Rows) yield return ToObject<T>(row, false);
}

在那里有yield return使得方法在需要结果之前实际上不执行任何代码(执行迭代)。

要使其工作,请遵循。net团队在LINQ实现中使用的相同模式:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
    if (source == null) throw Error.ArgumentNull("source");
    if (selector == null) throw Error.ArgumentNull("selector");
    return SelectIterator<TSource, TResult>(source, selector);
}
SelectIterator使用yield return每次返回一个项目。