{"id":23231,"date":"2019-05-14T16:47:18","date_gmt":"2019-05-14T23:47:18","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=23231"},"modified":"2019-05-14T16:47:18","modified_gmt":"2019-05-14T23:47:18","slug":"default-implementations-in-interfaces","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/default-implementations-in-interfaces\/","title":{"rendered":"Default implementations in interfaces"},"content":{"rendered":"<h2>Default implementations in interfaces<\/h2>\n<p>With last week&#8217;s posts <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-net-core-3-0-preview-5\/\">Announcing .NET Core 3.0 Preview 5<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-2019-version-16-1-preview-3\/\">Visual Studio 2019 version 16.1 Preview 3<\/a>, the last major feature of C# 8.0 is now available in preview.<\/p>\n<p>A big impediment to software evolution has been the fact that you couldn&#8217;t add new members to a public interface. You would break existing implementers of the interface; after all they would have no implementation for the new member!<\/p>\n<p>Default implementations help with that. An interface member can now be specified with a code body, and if an implementing class or struct does not provide an implementation of that member, no error occurs. Instead, the default implementation is used.<\/p>\n<p>Let&#8217;s say that we offer the following interface:<\/p>\n<pre class=\"lang:csharp decode:true\">interface ILogger\r\n{\r\n    void Log(LogLevel level, string message);\r\n}\r\n<\/pre>\n<p>An existing class, maybe in a different code base with different owners, implements <code>ILogger<\/code>:<\/p>\n<pre class=\"lang:csharp decode:true\">class ConsoleLogger : ILogger\r\n{\r\n    public void Log(LogLevel level, string message) { ... }\r\n}\r\n<\/pre>\n<p>Now we want to add another overload of the <code>Log<\/code> method to the interface. We can do that without breaking the existing implementation by providing a default implementation &#8211; a method body:<\/p>\n<pre class=\"lang:csharp decode:true\">interface ILogger\r\n{\r\n    void Log(LogLevel level, string message);\r\n    void Log(Exception ex) =&gt; Log(LogLevel.Error, ex.ToString());\r\n}\r\n<\/pre>\n<p>The <code>ConsoleLogger<\/code> still satisfies the contract provided by the interface: if it is converted to the interface and the new Log method is called it will work just fine: the interface&#8217;s default implementation is just called:<\/p>\n<pre class=\"lang:csharp decode:true\">public static void LogException(ConsoleLogger logger, Exception ex)\r\n{\r\n    ILogger ilogger = logger; \/\/ Converting to interface\r\n    ilogger.Log(ex);          \/\/ Calling new Log overload\r\n}\r\n<\/pre>\n<p>Of course an implementing class that does know about the new member is free to implement it in its own way. In that case, the default implementation is just ignored.<\/p>\n<p>The best way to get acquainted with default implementations is the <a href=\"https:\/\/docs.microsoft.com\/dotnet\/csharp\/tutorials\/default-interface-members-versions\">Tutorial: Update interfaces with default interface members in C# 8<\/a> on Microsoft Docs.<\/p>\n<p>Happy hacking!<\/p>\n<p>Mads<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Default implementations in interfaces With last week&#8217;s posts Announcing .NET Core 3.0 Preview 5 and Visual Studio 2019 version 16.1 Preview 3, the last major feature of C# 8.0 is now available in preview. A big impediment to software evolution has been the fact that you couldn&#8217;t add new members to a public interface. You [&hellip;]<\/p>\n","protected":false},"author":1379,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,756],"tags":[4,46],"class_list":["post-23231","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-csharp","tag-net","tag-c"],"acf":[],"blog_post_summary":"<p>Default implementations in interfaces With last week&#8217;s posts Announcing .NET Core 3.0 Preview 5 and Visual Studio 2019 version 16.1 Preview 3, the last major feature of C# 8.0 is now available in preview. A big impediment to software evolution has been the fact that you couldn&#8217;t add new members to a public interface. You [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/1379"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=23231"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23231\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=23231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=23231"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=23231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}