{"id":3033,"date":"2009-03-25T16:23:00","date_gmt":"2009-03-25T16:23:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2009\/03\/25\/how-to-use-linq-methods-to-compare-objects-of-custom-types\/"},"modified":"2019-02-14T15:42:22","modified_gmt":"2019-02-14T23:42:22","slug":"how-to-use-linq-methods-to-compare-objects-of-custom-types","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/how-to-use-linq-methods-to-compare-objects-of-custom-types\/","title":{"rendered":"How to use LINQ methods to compare objects of custom types"},"content":{"rendered":"<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">LINQ provides a convenient syntax and many useful methods for operating with collections of objects. However, to be correctly processed by LINQ comparison methods such as <\/font><span>Distinct<\/span><font face=\"Calibri\"> or <\/font><span>Intersect<\/span><font face=\"Calibri\">, a type must satisfy certain requirements.<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Let&rsquo;s take a look at the <\/font><span>Distinct<\/span><font face=\"Calibri\"> method, which returns all distinct objects from a collection.<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>List&lt;<\/span><span>int<\/span><span>&gt; numbers = <\/span><span>new<\/span><span> List&lt;<\/span><span>int<\/span><span>&gt; { 1, 1, 2, 3 };<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>var<\/span><span> distinctNumbers = numbers.Distinct();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>foreach<\/span><span> (<\/span><span>var<\/span><span> number <\/span><span>in<\/span><span> distinctNumbers)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>Console.WriteLine(number);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">The output is: <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">1<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">2<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">3<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">But what if you want to use the <\/font><span>Distinct<\/span><font face=\"Calibri\"> method for a collection of objects of your own type? For example, like this:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> <span>Number<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>int<\/span> Digital { <span>get<\/span>; <span>set<\/span>; }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>String<\/span> Textual { <span>get<\/span>; <span>set<\/span>; }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> <span>Program<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>static<\/span> <span>void<\/span> Main(<span>string<\/span>[] args)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>List<\/span>&lt;<span>Number<\/span>&gt; numbers = <span>new<\/span> <span>List<\/span>&lt;<span>Number<\/span>&gt; { <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>new<\/span> <span>Number<\/span> { Digital = 1, Textual = <span>&#8220;one&#8221;<\/span> }, <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>new<\/span> <span>Number<\/span> { Digital = 1, Textual = <span>&#8220;one&#8221;<\/span> } ,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>new<\/span> <span>Number<\/span> { Digital = 2, Textual = <span>&#8220;two&#8221;<\/span> } ,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>new<\/span> <span>Number<\/span> { Digital = 3, Textual = <span>&#8220;three&#8221;<\/span> } ,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>var<\/span> distinctNumbers = numbers.Distinct();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>foreach<\/span> (<span>var<\/span> number <span>in<\/span> distinctNumbers)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Console<\/span>.WriteLine(number.Digital);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">The code compiles, but the output is different:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">1<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">1<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">2<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">3<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Why did that happen? The answer is in the LINQ implementation details. To be correctly processed by the <\/font><span>Distinct<\/span><font face=\"Calibri\"> method, a type must implement the <\/font><span>IEquatable&lt;T&gt;<\/span><span><font face=\"Calibri\"> interface and provide its own <\/font><\/span><span>Equals<\/span><span><font face=\"Calibri\"> and <\/font><\/span><span>GetHashCode<\/span><span><font face=\"Calibri\"> methods.<\/p>\n<p><\/font><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><span><font face=\"Calibri\">So, the <\/font><\/span><span>Number<\/span><span><font face=\"Calibri\"> class from the previous example should actually look like this:<\/p>\n<p><\/font><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> <span>Number<\/span>: <span>IEquatable<\/span>&lt;<span>Number<\/span>&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>int<\/span> Digital { <span>get<\/span>; <span>set<\/span>; }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>String<\/span> Textual { <span>get<\/span>; <span>set<\/span>; }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>bool<\/span> Equa\nls(<span>Number<\/span> other)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Check whether the compared object is null.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span> (<span>Object<\/span>.ReferenceEquals(other, <span>null<\/span>)) <span>return<\/span> <span>false<\/span>;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Check whether the compared object references the same data.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span> (<span>Object<\/span>.ReferenceEquals(<span>this<\/span>, other)) <span>return<\/span> <span>true<\/span>;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Check whether the objects&rsquo; properties are equal.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> Digital.Equals(other.Digital) &amp;&amp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Textual.Equals(other.Textual);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ If Equals returns true for a pair of objects,<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ GetHashCode must return the same value for these objects.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>override<\/span> <span>int<\/span> GetHashCode()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Get the hash code for the Textual field if it is not null.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>int<\/span> hashTextual = Textual == <span>null<\/span> ? 0 : Textual.GetHashCode();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Get the hash code for the Digital field.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>int<\/span> hashDigital = Digital.GetHashCode();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>\/\/ Calculate the hash code for the object.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> hashDigital ^ hashTextual;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">But what if you cannot modify the type? What if it was provided by a library and you have no way of implementing the <\/font><span>IEquatable&lt;T&gt;<\/span><font face=\"Calibri\"> interface in this type? The answer is to create your own equality comparer and pass it as a parameter to the <\/font><span>Distinct<\/span><font face=\"Calibri\"> method. <\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">The equality comparer must implement the <\/font><span>IEqualityComparer&lt;T&gt;<\/span><span><font face=\"Calibri\"> interface and, again, provide <\/font><\/span><span>GetHashCode<\/span><span><font face=\"Calibri\"> and <\/font><\/span><span>Equals<\/span><span><font face=\"Calibri\"> methods.<\/p>\n<p><\/font><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><span><font face=\"Calibri\">Here is how the equality comparer for the original <\/font><\/span><span>Number<\/span><span><font face=\"Calibri\"> class might look:<\/p>\n<p><\/font><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> <span>NumberComparer<\/span> : <span>IEqualityComparer<\/span>&lt;<span>Number<\/span>&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>bool<\/span> Equals(<span>Number<\/span> x, <span>Number<\/span> y)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span><span>&nbsp;<\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span> (<span>Object<\/span>.ReferenceEquals(x, y)) <span>return<\/span> <span>true<\/span>;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span> (<span>Object<\/span>.ReferenceEquals(x, <span>null<\/span>) || <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Object<\/span>.ReferenceEquals(y, <span>null<\/span>))<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> <span>false<\/span>;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>return<\/span> x.Digital == y.Digital &amp;&amp; x.Textual == y.Textual;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>public<\/span> <span>int<\/span> GetHashCode(<span>Number<\/span> number)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>{<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>if<\/span> (<span>Object<\/span><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LINQ provides a convenient syntax and many useful methods for operating with collections of objects. However, to be correctly processed by LINQ comparison methods such as Distinct or Intersect, a type must satisfy certain requirements. Let&rsquo;s take a look at the Distinct method, which returns all distinct objects from a collection. List&lt;int&gt; numbers = new [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[3,1383],"class_list":["post-3033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-net-framework","tag-c"],"acf":[],"blog_post_summary":"<p>LINQ provides a convenient syntax and many useful methods for operating with collections of objects. However, to be correctly processed by LINQ comparison methods such as Distinct or Intersect, a type must satisfy certain requirements. Let&rsquo;s take a look at the Distinct method, which returns all distinct objects from a collection. List&lt;int&gt; numbers = new [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/3033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=3033"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/3033\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=3033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=3033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=3033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}