{"id":110873,"date":"2025-02-17T07:00:00","date_gmt":"2025-02-17T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110873"},"modified":"2025-02-15T08:03:19","modified_gmt":"2025-02-15T16:03:19","slug":"20250217-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250217-00\/?p=110873","title":{"rendered":"API design note: Beware of adding an &#8220;Other&#8221; enum value"},"content":{"rendered":"<p>Consider the following API:<\/p>\n<pre>enum class WidgetFlavor\r\n{\r\n    Vanilla,\r\n    Chocolate,\r\n    Strawberry,\r\n    <span style=\"border: solid 1px currentcolor;\">Other,<\/span>\r\n};\r\n\r\nWidgetFlavor GetWidgetFlavor(HWIDGET widget);\r\n<\/pre>\n<p>The idea here is that Widgets come in three flavors today, but we might add new flavors in the future, so we add an <code>Other<\/code> value to cover any future flavors.<\/p>\n<p>This is a problem.<\/p>\n<p>Suppose we do indeed add a new flavor <code>Mint<\/code> in the next version.<\/p>\n<pre>enum class WidgetFlavor\r\n{\r\n    Vanilla,\r\n    Chocolate,\r\n    Strawberry,\r\n    Other,\r\n    <span style=\"border: solid 1px currentcolor;\">Mint,<\/span>\r\n};\r\n<\/pre>\n<p>What flavor should you report if somebody calls <code>Get\u00adWidget\u00adFlavor<\/code> and the widget is mint?<\/p>\n<p>If you return <code>WidgetFlavor::<wbr \/>Mint<\/code>, then this will confuse code written with the Version\u00a01 API, because they expected to get <code>Other<\/code> for anything that isn&#8217;t vanilla, chocolate, or strawberry. The word &#8220;other&#8221; means &#8220;not mentioned elsewhere&#8221;, so the presence of an <code>Other<\/code> logically implies that the enumeration is exhaustive.<\/p>\n<p>On the other hand, you obviously should return <code>WidgetFlavor::<wbr \/>Mint<\/code> because that&#8217;s why you added the value to the enum in the first place!<\/p>\n<p>My recommendation is not to have an <code>Other<\/code> at all. Just document that the enumeration is open-ended, and programs should treat any unrecognized values as if they were &#8220;Other&#8221;. Any code that uses this enumeration will therefore put all unrecognized values into an app-defined &#8220;Other&#8221; category on their own. Now you can add <code>Mint<\/code>: New code will put minty widgets in a &#8220;Mint&#8221; category, and old code will continue to put them in the app=defined &#8220;Other&#8221; category.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What are you going to do when you add a new kind?<\/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-110873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>What are you going to do when you add a new kind?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110873","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=110873"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110873\/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=110873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}