2015-07-10 2 views
0

I have the following extension methods:метод расширения не бросает исключение, как и ожидалось

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>(); 
} 

The DataRow test пассы (он бросает ArgumentNullException нормально), а DataTable one нет (Безразлично 'хит метод или ничего не бросать).

У меня нет абсолютно никакой идеи, почему тест DataTable не работает (и DataRow - это нормально!).

(сначала я думал, что это была ошибка в моей Visual Studio, но the CI service that I use accused the same)

ответ

6

Я предполагаю, что IEnumerable<T> не просто для удовольствия, и что метод расширения фактически итератор.

Такой итератор, фактически не выполняется до момента исключения исключения, пока вы не начнете его итерацию.

+0

Черт, это делает весь смысл. Я полностью забыл о отсроченном исполнении. Возвращайся сразу же. – talles

1

Код, который вы отправили здесь, недостаточно, чтобы диагностировать проблему, потому что это вызвано тем, что скрыто за комментарием /// 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 возвращает один элемент в то время.

Смежные вопросы