{"id":39,"date":"2005-07-25T15:05:46","date_gmt":"2005-07-25T13:05:46","guid":{"rendered":"http:\/\/ken.friislarsen.net\/blog\/2005\/07\/25\/implementing-the-generic-ienumerable-interface\/"},"modified":"2005-07-25T15:05:46","modified_gmt":"2005-07-25T13:05:46","slug":"implementing-the-generic-ienumerable-interface","status":"publish","type":"post","link":"http:\/\/ken.friislarsen.net\/blog\/2005\/07\/25\/implementing-the-generic-ienumerable-interface\/","title":{"rendered":"Implementing the generic IEnumerable interface"},"content":{"rendered":"<p>Say you want to implement a class that implements the <code>IEnumerable<\/code> interface in C#.  Then you have two choices, either to implement the old-style non-generic <code>IEnumerable<\/code> interface or you can implements the generic <code>IEnumerable&lt;T&gt;<\/code> interface.  Given those choices we of course want to implement the new generic version of the interface.  Because otherwise lots of boxing and unboxing will happen when <code>T<\/code> is a value type, with the non-generic version you will not be able to conveniently use the <code>Current<\/code> property of your enumerator, and for general type-safety goodness.<\/p>\n<p>Thus, you set out to implement the generic version.  For example, let say we want to implement a class that enumerates all the integers staring from a given offset.  First we might try this:<\/p>\n<pre>\nusing System.Collections.Generic;\nclass Ints : IEnumerable&lt;int&gt; {\n    private readonly int offset;\n    public Ints(int o) { offset = o; }\n    public IEnumerator&lt;int&gt; GetEnumerator() {\n        int i = offset;\n        while( true ) yield return i++;\n    }\n}\n<\/pre>\n<p>But then the compiler complains:<\/p>\n<pre>\nerror CS0535: 'Ints' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'\n<\/pre>\n<p>Thank you for letting us know nice compiler.  But we don&#8217;t want <code>Ints<\/code> to implement the non-generic interface.  We want it to implement the generic interface.<\/p>\n<p>Reading up on the documentation will reveal that the generic interface inherits from the non-generic interface. What a wonderful design.  Thankfully we can make a general work-around for this design flaw in the library.  Just add a non-generic method that calls the generic method:<\/p>\n<pre>\n    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }\n<\/pre>\n<p>Once the author of <a href=\"http:\/\/www.dina.kvl.dk\/~sestoft\/csharpprecisely\/\">my favorite C# book<\/a> returns from vacation. I&#8217;ll complain to him that the section about <code>IEnumerable<\/code> didn&#8217;t make it clear that if you want to implement the generic interface you also have to implement the non-generic interface.<\/p>\n<p><b>Update:<\/b> It turns out that <a href=\"http:\/\/www.dina.kvl.dk\/~sestoft\/csharpprecisely\/errata.html\">the errata<\/a> to <a href=\"http:\/\/www.dina.kvl.dk\/~sestoft\/csharpprecisely\">C# Precisely<\/a> already mentions this curriousity.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Say you want to implement a class that implements the IEnumerable interface in C#. Then you have two choices, either to implement the old-style non-generic IEnumerable interface or you can implements the generic IEnumerable&lt;T&gt; interface. Given those choices we of course want to implement the new generic version of the interface. Because otherwise lots of <a class=\"read-more\" href=\"http:\/\/ken.friislarsen.net\/blog\/2005\/07\/25\/implementing-the-generic-ienumerable-interface\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,4,3],"tags":[],"class_list":["post-39","post","type-post","status-publish","format-standard","hentry","category-c","category-coding","category-general"],"_links":{"self":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts\/39","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/comments?post=39"}],"version-history":[{"count":0,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts\/39\/revisions"}],"wp:attachment":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/media?parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/categories?post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/tags?post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}