{"id":942,"date":"2011-02-09T15:30:07","date_gmt":"2011-02-09T14:30:07","guid":{"rendered":"http:\/\/blog.eweibel.net\/?p=942"},"modified":"2011-02-09T16:00:56","modified_gmt":"2011-02-09T15:00:56","slug":"enums-and-inheritance-in-net","status":"publish","type":"post","link":"https:\/\/blog.eweibel.net\/?p=942","title":{"rendered":"Enums and inheritance in .Net"},"content":{"rendered":"<p>In one of my current projects I had the following code (I simplified the code a bit):<\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d9dfda92-84e0-484d-8709-7abaad93012b\" class=\"wlWriterSmartContent\">\n<pre class=\"brush: c#;\">public string ConnectionString\n{\n\tget\n\t{\n\t\tswitch(this.Importer)\n\t\t{\n\t\t\tcase Importer.SqlServer:\n\t\t\t\treturn &quot;Server=localhost;Database=Northwind&quot;;\n\t\t\tcase Importer.SqlServerOleDb:\n\t\t\t\treturn&quot;Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind&quot;;\n\t\t\tdefault:\n\t\t\t\tthrow new NotSupportedException(\n\t\t\t\tstring.Format(&quot;Importer {0} is not supported yet.&quot;, this.Importer));\n\t\t}\n\t}\n}<\/pre>\n<\/div>\n<p>After running the code coverage tool (<a href=\"http:\/\/www.jetbrains.com\/dotcover\/\" target=\"_blank\">dotCover from JetBrains<\/a>) I received the following picture:<\/p>\n<p><a href=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/CodeCoverage.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px\" title=\"CodeCoverage\" border=\"0\" alt=\"CodeCoverage\" src=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/CodeCoverage_thumb.png\" width=\"592\" height=\"190\" \/><\/a><\/p>\n<p><strong>First idea<\/strong><\/p>\n<p>So, my code was clear and understandable, but obviously not fully tested (green: covered by tests, red: not covered). I asked me the question, how could I test the rest of the method.<\/p>\n<p>My idea was to extend the enum:<\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d2ecf493-5bb1-4d69-903a-c1b2b398a9f1\" class=\"wlWriterSmartContent\">\n<pre class=\"brush: c#;\">[TestFixture]\npublic class ConfigurationTest\n{\n        #region Test methods\n        #endregion\n\n        private enum TestImporter : Importer\n        {\n            Test\n        }\n}<\/pre>\n<\/div>\n<p>But the compiler and the <a href=\"http:\/\/www.jetbrains.com\/resharper\/\" target=\"_blank\">ReSharper<\/a> weren\u2019t happy with my idea: \u201cType byte, sbyte, short, ushort, int, uint, long, or ulong expected\u201d. I was surprised at this error: Why it isn\u2019t possible to make a subclass of an enum?<\/p>\n<p>I found the explanation first on <a href=\"http:\/\/stackoverflow.com\/questions\/757684\/enum-inheritance\" target=\"_blank\">stackoverflow<\/a> and then in the <a href=\"http:\/\/www.ecma-international.org\/publications\/files\/ECMA-ST\/Ecma-335.pdf\" target=\"_blank\">specification of the Common Language Infrastructure (CLI, section 8.5.2)<\/a>:<\/p>\n<blockquote>\n<p>It shall derive from System.Enum<\/p>\n<\/blockquote>\n<p>An enum in .Net has to derive directly from enum, it isn\u2019t possible to inherit from another enum. So, the enums in .Net don\u2019t follow the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Open\/closed_principle\" target=\"_blank\">open\/closed principle<\/a> (OCP). With the OCP you don\u2019t modify a class when you want to extend it, you inherit from it and do the extensions in the subclass:<\/p>\n<blockquote>\n<p>Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.<\/p>\n<\/blockquote>\n<p><strong>Second idea<\/strong><\/p>\n<p>My code wasn\u2019t tested and is it really not possible to test it? Well, it is possible, but the code isn\u2019t very nice (hard cast):<\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e9de2aa4-958f-40ba-8d36-c3538f662de8\" class=\"wlWriterSmartContent\">\n<pre class=\"brush: c#;\"> [Test]\n[ExpectedException(typeof(NotSupportedException))]\npublic void TestConnectionString_With_Invalid_Enum()\n{\n\t\/\/ Arrange\n\tthis.Configuration.Importer = (Importer) 100;\n\n\t\/\/ Act\n\tstring strConnectionstring = this.Configuration.ConnectionString;\n}<\/pre>\n<\/div>\n<p><strong>Conclusion<\/strong><\/p>\n<p>I my current decision is to leave the code as it is. The reasons were the following:<\/p>\n<ul>\n<li>Readability is very important <\/li>\n<li>You have to use default or a return value, otherwise the code will not compile <\/li>\n<li>I want that my tests will fail when I extend the enum and test the new value. So it is easier to find the places where I have to adjust something (but it smells like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Shotgun_surgery\" target=\"_blank\">shotgun surgery<\/a>\u2026) <\/li>\n<li>The code is testable, but you have to create an invalid enum value by hard casting an integer (and that is ugly) <\/li>\n<\/ul>\n<p>I\u2019m not really convinced with my current decision, but I could live with it. How would you design the code? Are there any better ways to test the code?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In one of my current projects I had the following code (I simplified the code a bit): public string ConnectionString { get { switch(this.Importer) { case Importer.SqlServer: return &quot;Server=localhost;Database=Northwind&quot;; case Importer.SqlServerOleDb: return&quot;Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind&quot;; default: throw new NotSupportedException( string.Format(&quot;Importer {0} is not supported yet.&quot;, this.Importer)); } } } After running the code coverage tool (dotCover from JetBrains) I received the following picture: First idea So, my code was clear and understandable, but obviously not fully tested (green: covered by tests,&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/blog.eweibel.net\/?p=942\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[13,10],"tags":[],"class_list":["post-942","post","type-post","status-publish","format-standard","hentry","category-net","category-testing"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/plOV9-fc","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":745,"url":"https:\/\/blog.eweibel.net\/?p=745","url_meta":{"origin":942,"position":0},"title":"ConfORM &ndash; Another NHibernate mapping possibility","author":"Patrick","date":"1. Sep 2010","format":false,"excerpt":"I recently hold two presentations at the .Net User Group Bern (DNUG) with Ren\u00e9 Leupold about object relational mapping in the .Net world. We showed Entity Framework 4.0 and NHibernate. My part was NHibernate. You could download the slides and samples from the DNUG website. In the two presentations I\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"ConfOrmBigTransparent","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/ConfOrmBigTransparent_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":459,"url":"https:\/\/blog.eweibel.net\/?p=459","url_meta":{"origin":942,"position":1},"title":"Fail Fast principle","author":"Patrick","date":"22. Sep 2009","format":false,"excerpt":"Recently I received a NullReference-Exception when I called another method from a foreign component. Fortunately I had the source code of this component and I found the following code: [code language=\"csharp\"] public class AgeValidator { public Dictionary Config { get; set; } public bool Validate(int nAge) { int nMinAge =\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":34,"url":"https:\/\/blog.eweibel.net\/?p=34","url_meta":{"origin":942,"position":2},"title":"Are 100% code coverage reasonable?","author":"Patrick","date":"2. Mar 2009","format":false,"excerpt":"When you use a code coverage tool one of the first question is what is a good code coverage. Recently I listened to different podcasts (stackoverflow, scott hanselman) where they discuss this topic. I wasn't really surprised that there wasn't one unique opinion.One opinion was that 100% is a good\u2026","rel":"","context":"In &quot;Software architecture&quot;","block_context":{"text":"Software architecture","link":"https:\/\/blog.eweibel.net\/?cat=4"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1086,"url":"https:\/\/blog.eweibel.net\/?p=1086","url_meta":{"origin":942,"position":3},"title":"Grooming your code base","author":"Patrick","date":"1. Sep 2011","format":false,"excerpt":"When you're doing Test Driven Development (TDD), it's in the process: Red-Green-Refactor. Refactoring doesn't only mean to improve your new code, it is also important to make your existing code nicer. If you are a .NET Developer, then you should have the Visual Studio Add-on ReSharper. With this tool you\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"Fotolia_32643902_S","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/Fotolia_32643902_S_thumb1.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1353,"url":"https:\/\/blog.eweibel.net\/?p=1353","url_meta":{"origin":942,"position":4},"title":"NDC 2014","author":"Patrick","date":"16. Jun 2014","format":false,"excerpt":"I attended this year's NDC (Norwegian developer conference) in Oslo. It was a very interesting conference, but as a short summary, it saw something like a consolidation. JavaScript - as some people say in its fourth generation (Simple Scripts, AJAX, MVC-Framworks, SPA) - is finally accepted as a language like\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/ndclogo2014.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":890,"url":"https:\/\/blog.eweibel.net\/?p=890","url_meta":{"origin":942,"position":5},"title":"Hunting performance issues","author":"Patrick","date":"17. Jan 2011","format":false,"excerpt":"Recently I received the lead over a performance optimization project for a software product.\u00a0 It isn't something extraordinary for a software architect, because as a software architect you have to know what's critical for a software system in a specific environment. Some of my co-workers may now smile a bit:\u2026","rel":"","context":"In &quot;Software architecture&quot;","block_context":{"text":"Software architecture","link":"https:\/\/blog.eweibel.net\/?cat=4"},"img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/image_thumb9.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=942"}],"version-history":[{"count":7,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/942\/revisions"}],"predecessor-version":[{"id":949,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/942\/revisions\/949"}],"wp:attachment":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}