{"id":104008,"date":"2020-07-27T07:00:00","date_gmt":"2020-07-27T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104008"},"modified":"2020-07-26T22:43:43","modified_gmt":"2020-07-27T05:43:43","slug":"20200727-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200727-00\/?p=104008","title":{"rendered":"How do I set multiple items to a Windows Runtime vector in a single call?"},"content":{"rendered":"<p>Suppose you want to set multiple items to a Windows Runtime <code>IVector&lt;T&gt;<\/code>. This is common in the cases where the system provides a vector that you are expected to fill with stuff. For example:<\/p>\n<pre>\/\/ C#\r\nvar picker = new FileOpenPicker();\r\npicker.FileTypeFilter.Add(\".bmp\");\r\npicker.FileTypeFilter.Add(\".gif\");\r\npicker.FileTypeFilter.Add(\".jpg\");\r\npicker.FileTypeFilter.Add(\".png\");\r\n<\/pre>\n<p>Surely there is an easier way to do this than calling <code>Add<\/code> multiple times, right?<\/p>\n<p>Yes, there is an easier way, but the easier way depends on what language you are using. Each language expresses the Windows Runtime <code>IVector&lt;T&gt;<\/code> in its own language-specific way.<\/p>\n<p>C# projects the <code>IVector&lt;T&gt;<\/code> as an <code>System.Collections.Generic.IList&lt;T&gt;<\/code>. You can use <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/classes-and-structs\/object-and-collection-initializers\"> object and collection initializer syntax<\/a> to fill the collection as part of the object initialization.<\/p>\n<pre>\/\/ C#\r\nvar picker = new FileOpenPicker()\r\n    {\r\n        FileTypeFilter = { \".bmp\", \".gif\", \".jpg\", \".png\" }\r\n    };\r\n<\/pre>\n<p>Note, however, that this syntax works only in an object initializer.<\/p>\n<pre>\/\/ doesn't work\r\n<i>picker.FileTypeFilter = { \".bmp\", \".gif\", \".jpg\", \".png\" };<\/i>\r\n<\/pre>\n<p>You might be tempted to use <code>List&lt;T&gt;.AddRange()<\/code>, but that doesn&#8217;t work either because what you have is an <code>IList&lt;T&gt;<\/code>, not a <code>List&lt;T&gt;<\/code>. Many people have solved this problem by using <a href=\"https:\/\/stackoverflow.com\/questions\/1474863\/addrange-to-a-collection\"> an extension method<\/a>.<\/p>\n<p>C++\/WinRT exposes the <code>IVector&lt;T&gt;<\/code> very close to how it is defined in the ABI. In particular, there is a <code>Replace\u00adAll<\/code> method.<\/p>\n<pre>\/\/ C++\/WinRT\r\nauto picker = FileOpenPicker();\r\npicker.FileTypeFilter().\r\n    ReplaceAll({ L\".bmp\", L\".gif\", L\".jpg\", L\".png\" });\r\n<\/pre>\n<p>C++\/CX is a bit more annoying because you have to pass a <code>Platform::<\/code><code>Array^<\/code> to the <code>Replace\u00adAll<\/code> method, and those <code>Array^<\/code> types are frustrating to manufacture.<\/p>\n<pre>\/\/ C++\/CX\r\nauto picker = ref new FileOpenPicker();\r\nString^ extensions[]{ L\".bmp\", L\".gif\", L\".jpg\", L\".png\" };\r\npicker-&gt;FileTypeFilter-&gt;ReplaceAll(\r\n    ArrayReference&lt;String^&gt;(extensions, _ARRAYSIZE(extensions)));\r\n<\/pre>\n<p>Sadly, there are no deduction guides for <code>Array\u00adReference<\/code> so you end up having to repeat <code>String^<\/code>.<\/p>\n<p>JavaScript projects <code>IVector&lt;T&gt;<\/code> as a native JavaScript <code>Array<\/code>, and those objects have quite a rich panoply of available methods. One that is useful for us today is <code>splice<\/code>.<\/p>\n<pre>\/\/ JavaScript\r\nvar picker = new Windows.Storage.Pickers.FileOpenPicker();\r\npicker.fileTypeFilter.splice(0, 0, \".bmp\", \".gif\", \".jpg\", \".png\");\r\n<\/pre>\n<p>The JavaScript projection is kind enough to project the original <code>replaceAll<\/code> method as well, which leads us to this somewhat simpler version:<\/p>\n<pre>\/\/ JavaScript\r\nvar picker = new Windows.Storage.Pickers.FileOpenPicker();\r\npicker.fileTypeFilter.replaceAll([ \".bmp\", \".gif\", \".jpg\", \".png\" ]);\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>It depends on the language projection.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-104008","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It depends on the language projection.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=104008"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104008\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=104008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}