{"id":108017,"date":"2023-04-05T07:00:00","date_gmt":"2023-04-05T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=108017"},"modified":"2023-04-04T19:00:07","modified_gmt":"2023-04-05T02:00:07","slug":"20230405-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230405-00\/?p=108017","title":{"rendered":"How do I modify the contents of a boxed Windows Runtime value?"},"content":{"rendered":"<p>When you box a value in the Windows Runtime, it&#8217;s boxed for good. You can&#8217;t change the value inside a box. Most of the time, it&#8217;s pretty obvious that you can&#8217;t do it:<\/p>\n<pre>\/\/ C#\r\nvoid UpdateX(Nullable&lt;Point&gt; pt)\r\n{\r\n  if (pt != null) {\r\n    \/\/ Error: Cannot modify the return value of Point?.Value\r\n    \/\/ because it is not a variable\r\n    pt.Value.X = 42.0;\r\n  }\r\n}\r\n\r\n\/\/ C++\/WinRT\r\nvoid UpdateX(IReference&lt;Point&gt; pt)\r\n{\r\n  if (pt != nullptr) {\r\n    \/\/ Error: expression must be a modifiable lvalue\r\n    pt.Value().X = 42.0;\r\n  }\r\n}\r\n\r\n\/\/ C++\/CX\r\nvoid UpdateX(IBox&lt;Point&gt;^ pt)\r\n{\r\n  if (pt != nullptr) {\r\n    \/\/ Error: lvalue required as left operand of assignment\r\n    pt-&gt;Value.X = 42.0;\r\n  }\r\n}\r\n<\/pre>\n<p>In the case of C++\/WinRT, I think the error is unlikely to occur because you&#8217;re clearly modifying the result of a function call.<\/p>\n<p>But for C# and C++\/CX, the property syntax looks a lot like a member variable access, and you may not realize that the property value is secretly the result of a function call.<\/p>\n<p>Boxed values are read-only. If you look at <a href=\"https:\/\/docs.microsoft.com\/uwp\/api\/windows.foundation.ireference-1?view=winrt-22621\"> <code>IReference&lt;T&gt;<\/code><\/a> (which is the interface at the ABI layer that is used for Windows Runtime boxed values), you&#8217;ll see that there is a read-only <code>Value<\/code> property, but no method for setting a new value. Once a value is boxed, you can&#8217;t change it.<\/p>\n<p>But what if you want to change it?<\/p>\n<p>You&#8217;ll have to box up a new value and then ask everybody to switch over to it.<\/p>\n<pre>\/\/ C#\r\nNullable&lt;Point&gt; UpdateX(Nullable&lt;Point&gt; pt)\r\n{\r\n  if (pt != null) {\r\n    var value = pt.Value;\r\n    value.X = 42.0;\r\n    pt = value; \/\/ box up a new value\r\n  }\r\n  return pt;\r\n}\r\n\r\n\/\/ C++\/WinRT\r\nIReference&lt;Point&gt; UpdateX(IReference&lt;Point&gt; pt)\r\n{\r\n  if (pt != nullptr) {\r\n    auto value = pt.Value();\r\n    value.X = 42.0;\r\n    pt = winrt::box_value(value); \/\/ box up a new value\r\n  }\r\n  return pt;\r\n}\r\n\r\n\/\/ C++\/CX\r\nIBox&lt;Point&gt; UpdateX(IBox&lt;Point&gt;^ pt)\r\n{\r\n  if (pt != nullptr) {\r\n    auto value = pt-&gt;Value;\r\n    value.X = 42.0;\r\n    pt = value; \/\/ box up a new value\r\n  }\r\n  return pt;\r\n}\r\n<\/pre>\n<p>Of course, you now have to take the updated boxed value and update wherever you got it from.<\/p>\n<pre>\/\/ C#\r\nflyoutShowOptions.Position = UpdateX(flyoutShowOptions.Position);\r\n\r\n\/\/ C++\/WinRT\r\nflyoutShowOptions.Position(UpdateX(flyoutShowOptions.Position()));\r\n\r\n\/\/ C++\/CX\r\nflyoutShowOptions-&gt;Position = UpdateX(flyoutShowOptions-&gt;Position);\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Once it&#8217;s in the box, you can&#8217;t change it.<\/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-108017","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Once it&#8217;s in the box, you can&#8217;t change it.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108017","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=108017"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108017\/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=108017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=108017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=108017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}