{"id":771,"date":"2009-11-04T00:15:04","date_gmt":"2009-11-03T23:15:04","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=771"},"modified":"2021-03-11T09:44:57","modified_gmt":"2021-03-11T08:44:57","slug":"linq-cast-catch","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2009\/11\/linq-cast-catch\/","title":{"rendered":"LINQ: cast-catch"},"content":{"rendered":"<p>In this post I\u2019ll explain a little catch in LINQ, which may some beginners fall into: What\u2019s the difference between those two queries?   <\/p>\n<pre class=\"csharpcode\">IEnumerable&lt;Person&gt; listOfEntities = LoadData();\n<span class=\"rem\">\/\/ First version of the query<\/span>\nvar resultV1 = from p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Contains(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;\n<span class=\"rem\">\/\/ Second version of the query<\/span>\nvar resultV2 = from Person p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Equals(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;<\/pre>\n<p>No difference? A big difference? When you run the code above both queries will return the same result. So it seems that there\u2019s no difference.<\/p>\n<p>Now time passes, some requirements change which requires you to change the type of \u2018listOfEntities\u2019 and \u2018LoadData()\u2019 to \u2018IEnumerable&lt;Animal&gt;\u2019. Of course the Animal has also a name:<\/p>\n<pre class=\"csharpcode\">IEnumerable&lt;Animal&gt; listOfEntities = LoadData();\n<span class=\"rem\">\/\/ First version of the query<\/span>\nvar resultV1 = from p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Contains(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;\n<span class=\"rem\">\/\/ Second version of the query<\/span>\nvar resultV2 = from Person p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Equals(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;<br \/><\/pre>\n<pre class=\"csharpcode\">&#160;<\/pre>\n<p>So we\u2019ve changed everything to Animal. Unfortunately we as busy developer have missed to changed \u2018from Person p\u2019 to \u2018from Animal p\u2019. But the compiler is still happy. When run the program we get a InvalidCastException in the result of the second query. So there quite a big difference between the first and the second query. The first one operates on the type of given collection. The second query casts the data into \u2018Person\u2019. This cast is indented for the old, non-generic collections or data stores. But here it actually introduces a potential fault.<\/p>\n<p>It get obvious when you change the LINQ-syntax to the lambda-expression-syntax:<\/p>\n<pre class=\"csharpcode\"><span class=\"rem\">\/\/ First version of the query<\/span>\nvar allV1 = from p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Contains(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;\n<span class=\"rem\">\/\/ same as<\/span>\nvar allV1_ = listOfEntities.Where(p =&gt; p.Name.Contains(<span class=\"str\">&quot;a&quot;<\/span>));\n<span class=\"rem\">\/\/ Second version of the query<\/span>\nvar allV2 = from Person p <span class=\"kwrd\">in<\/span> listOfEntities\n               <span class=\"kwrd\">where<\/span> p.Name.Equals(<span class=\"str\">&quot;a&quot;<\/span>)\n               select p;\n<span class=\"rem\">\/\/ same as<\/span>\nvar allV2_ = listOfEntities.Cast&lt;Person&gt;().Where(p =&gt; p.Name.Equals(<span class=\"str\">&quot;a&quot;<\/span>));<\/pre>\n<p>In conclusion: \u2018from varName in collection\u2019 is not the same as \u2018from Type varName in collection\u2019. In the first version, the \u2018varName\u2019 is automatically the type of the elements in the collection. The second version casts each element of the collection to the given type. You should always take the first version, since it will produce a compiler-error when something is wrong. The second version is only good for old, non-generic collections or for data stores.<\/p>\n<p>Code: <a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2009\/11\/Program.cs\">LinqCatch.cs<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post I\u2019ll explain a little catch in LINQ, which may some beginners fall into: What\u2019s the difference between those two queries? IEnumerable&lt;Person&gt; listOfEntities = LoadData(); \/\/ First version&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126],"tags":[21,24,155],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/771"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=771"}],"version-history":[{"count":7,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/771\/revisions"}],"predecessor-version":[{"id":3827,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/771\/revisions\/3827"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}