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

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -