{"id":123,"date":"2009-12-03T07:00:56","date_gmt":"2009-12-03T05:00:56","guid":{"rendered":"http:\/\/www.limilabs.com\/blog\/?p=123"},"modified":"2012-02-15T15:23:07","modified_gmt":"2012-02-15T13:23:07","slug":"finder-for-any-ienumerable","status":"publish","type":"post","link":"https:\/\/www.limilabs.com\/blog\/finder-for-any-ienumerable","title":{"rendered":"Finder for any IEnumerable"},"content":{"rendered":"<p>NHibernate requires you to use <em>IList&lt;T&gt;<\/em> properties a lot:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic IList&lt;process&gt; Processes { get; set; }\r\n<\/pre>\n<p><strong>Searching <\/strong>through them is a real pain especially when you live in .NET 2.0 world:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic List&lt;processModel&gt; GetDeleted()\r\n{\r\n    List&lt;process&gt; list= new List&lt;process&gt;();\r\n    foreach (Process process in this.Processes)\r\n    {\r\n        if (process.IsDeleted)\r\n            list.Add(process);\r\n    }\r\n    return list;\r\n}\r\n<\/pre>\n<p>If you can&#8217;t move your project to .NET 3.5 and use extension methods here&#8217;s the solution for you.<\/p>\n<p>This is the simple class for making searches on any <em>IEnumerable&lt;T&gt;<\/em> easier:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic List&lt;processModel&gt; GetDeleted()\r\n{\r\n        return Finder.Create(this.Processes)\r\n                .FindAll(x =&gt; x.IsDeleted);\r\n}\r\n<\/pre>\n<p>Nice, isn&#8217;t it?<\/p>\n<p>The <strong>Finder class<\/strong> itself:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class Finder\r\n{\r\n    public static Finder&lt;t&gt; Create&lt;t&gt;(IEnumerable&lt;t&gt; list)\r\n    {\r\n        return new Finder&lt;t&gt;(list);\r\n    }\r\n};\r\n\r\npublic class Finder&lt;t&gt;\r\n{\r\n    private readonly IEnumerable&lt;t&gt; _list;\r\n\r\n    public Finder(IEnumerable&lt;t&gt; list)\r\n    {\r\n        _list = list;\r\n    }\r\n\r\n    public T Find(Predicate&lt;t&gt; func)\r\n    {\r\n        foreach (T element in _list)\r\n        {\r\n            if (func(element))\r\n                return element;\r\n        }\r\n        return default(T);\r\n    }\r\n\r\n    public List&lt;t&gt; FindAll(Predicate&lt;t&gt; func)\r\n    {\r\n        List&lt;t&gt; list = new List&lt;t&gt;();\r\n        foreach (T element in _list)\r\n        {\r\n            if (func(element))\r\n                list.Add(element);\r\n        }\r\n        return list;\r\n    }\r\n\r\n    public ReadOnlyCollection&lt;t&gt; FindAllAsReadOnly(Predicate&lt;t&gt; func)\r\n    {\r\n        return new ReadOnlyCollection&lt;t&gt;(this.FindAll(func));\r\n    }\r\n\r\n    public bool Contains(Predicate&lt;t&gt; func)\r\n    {\r\n        foreach (T element in _list)\r\n        {\r\n            if (func(element))\r\n                return true;\r\n        }\r\n        return false;\r\n    }\r\n};\r\n<\/pre>\n<p>and some <strong>tests<\/strong>:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;TestFixture]\r\npublic class FinderTest\r\n{\r\n    &#x5B;Test]\r\n    public void FindAll_ForValueType()\r\n    {\r\n        List&lt;int&gt; list = new List&lt;int&gt; { 1, 2, 10, 12 };\r\n        Finder&lt;int&gt; finder = Finder.Create(list);\r\n        Assert.AreEqual(1, finder.FindAll(x =&gt; x == 1).Count);\r\n    }\r\n\r\n    &#x5B;Test]\r\n    public void FindAll_ForRefType()\r\n    {\r\n        List&lt;box&gt; list = new List&lt;box&gt; { new Box(1), new Box(1), new Box(15) };\r\n        Finder&lt;box&gt; finder = Finder.Create(list);\r\n        Assert.AreEqual(2, finder.FindAll(x =&gt; x.Id == 1).Count);\r\n    }\r\n\r\n    &#x5B;Test]\r\n    public void FindAllAsReadOnly_Find_ForRefType()\r\n    {\r\n        List&lt;box&gt; list = new List&lt;box&gt; { new Box(1), new Box(1), new Box(15) };\r\n        Finder&lt;box&gt; finder = Finder.Create(list);\r\n        ReadOnlyCollection&lt;box&gt; only = finder.FindAllAsReadOnly(x =&gt; x.Id == 1);\r\n        Assert.AreEqual(2, only.Count);\r\n    }\r\n\r\n    &#x5B;Test]\r\n    public void Find_ForValueType()\r\n    {\r\n        List&lt;int&gt; list = new List&lt;int&gt; { 1 ,2, 10, 12 };\r\n        Finder&lt;int&gt; finder = Finder.Create(list);\r\n        Assert.AreEqual(1, finder.Find(x =&gt; x == 1));\r\n        Assert.AreEqual(12, finder.Find(x =&gt; x == 12));\r\n        Assert.AreEqual(0, finder.Find(x =&gt; x == 999));\r\n    }\r\n\r\n    &#x5B;Test]\r\n    public void Find_ForRefType()\r\n    {\r\n        List&lt;box&gt; list = new List&lt;box&gt; { new Box(21),  new Box(2),  new Box(15) };\r\n        Finder&lt;box&gt; finder = Finder.Create(list);\r\n        Assert.AreEqual(21, finder.Find(x =&gt; x.Id == 21).Id);\r\n        Assert.AreEqual(2, finder.Find(x =&gt; x.Id == 2).Id);\r\n        Assert.AreEqual(null, finder.Find(x =&gt; x.Id == 999));\r\n    }\r\n\r\n    &#x5B;Test]\r\n    public void Find_ForEmptyList()\r\n    {\r\n        Finder&lt;box&gt; finder = Finder.Create(new List&lt;box&gt;());\r\n        Assert.IsNull(finder.Find(x =&gt; x.Id == 21));\r\n        Assert.IsNull(finder.Find(x =&gt; x.Id == 2));\r\n        Assert.IsNull(finder.Find(x =&gt; x.Id == 999));\r\n    }\r\n\r\n    internal class Box\r\n    {\r\n        readonly int _id;\r\n\r\n        public int Id\r\n        {\r\n            get { return _id; }\r\n        }\r\n\r\n        public Box(int id)\r\n        {\r\n            _id = id;\r\n        }\r\n    }\r\n} ;\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>NHibernate requires you to use IList&lt;T&gt; properties a lot: public IList&lt;process&gt; Processes { get; set; } Searching through them is a real pain especially when you live in .NET 2.0 world: public List&lt;processModel&gt; GetDeleted() { List&lt;process&gt; list= new List&lt;process&gt;(); foreach (Process process in this.Processes) { if (process.IsDeleted) list.Add(process); } return list; } If you can&#8217;t [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[15],"class_list":["post-123","post","type-post","status-publish","format-standard","hentry","category-programming","tag-c"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/123"}],"collection":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/comments?post=123"}],"version-history":[{"count":3,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/123\/revisions"}],"predecessor-version":[{"id":2507,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/123\/revisions\/2507"}],"wp:attachment":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/media?parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}