c# - Method should throw exception but it doesn't -
i wrote small extensionmethod finds indexes of given string in ienumerable.
public static ienumerable<int> findindexesof(this ienumerable<string> itemlist, string indexestofind) { if (itemlist == null) throw new argumentnullexception("itemlist"); if (indexestofind == null) throw new argumentnullexception("indextofind"); list<string> enumerable = itemlist list<string> ?? itemlist.tolist(); (int = 0; < enumerable.count(); i++) { if (enumerable[i] == indexestofind) yield return i; } }
as can see above, argumentnullexception thrown if itemlist null. plain , simple.
when running unittest on above method, expect , exception of type argumentnullexception, because itemlist null. however, test comes out false because no exception gets thrown.
how possible? logic seems quite clear. see test below.
[testmethod] [expectedexception(typeof(argumentnullexception))] public void findindexesoftest2() { string[] items = null; ienumerable<int> indexes = items.findindexesof("one"); }
where going wrong in logic; why not throwing argumentnullexception?
the problem enumerators using yield
lazily evaluated.
since you're not iterating on collection returned, method hasn't executed.
the correct way split method in two:
public static ienumerable<int> findindexesof(this ienumerable<string> itemlist, string indexestofind) { if (itemlist == null) throw new argumentnullexception("itemlist"); if (indexestofind == null) throw new argumentnullexception("indextofind"); return findindexesofimpl(itemlist, indexestofind); } private static ienumerable<int> findindexesofimpl(this ienumerable<string> itemlist, string indexestofind) { list<string> enumerable = itemlist list<string> ?? itemlist.tolist(); (int = 0; < enumerable.count(); i++) { if (enumerable[i] == indexestofind) yield return i; } }
here first method execute when call it, , return lazily evaluated enumerator hasn't, until iterate on it.
though, suggest change latter method here lazily evaluated. fact method caches entire itemlist
able use indexes unnecessary, , can in fact rewrite without it:
public static ienumerable<int> findindexesofimpl(this ienumerable<string> itemlist, string indexestofind) { var index = 0; foreach (var item in itemlist) { if (item == indexestofind) yield return index; index++; } }
you can use linq extension methods though involves constructing temporary object each element, unsure whether worth it, i'd go 1 above here instead:
public static ienumerable<int> findindexesofimpl(this ienumerable<string> itemlist, string indexestofind) { return itemlist .select((item, index) => new { item, index }) .where(element => element.item == indexestofind) .select(element => element.index); }
with last method can move main method because you're no longer using yield
:
public static ienumerable<int> findindexesof(this ienumerable<string> itemlist, string indexestofind) { if (itemlist == null) throw new argumentnullexception("itemlist"); if (indexestofind == null) throw new argumentnullexception("indextofind"); return itemlist .select((item, index) => new { item, index }) .where(element => element.item == indexestofind) .select(element => element.index); }
Comments
Post a Comment