DEV Community

Frederik Van Lierde
Frederik Van Lierde

Posted on

Adding Default Behaviour to Interfaces in dotNet

A strange question you may think, as interfaces define a contract and every class (or struct) that implements that interface must provide an implementation of the member's methods.

Why Adding Extension to an Interface

When you have an Interface, used by many classes, and you want to add a method, this means you need to update all your classes implementing the interface, including testing.

This is not always the preferred way as it can be time-consuming and not all classes will be using the new method.

Default Behaviour is good for backwards compatibility

Default Behaviour for Interfaces with C#8

public interface ISearchResult
{
   string GetPublicUrl();
   string GetTitle();
   string GetDescription();

   public void GetAuthorName(Exception ex)
   {
      return "";
    }
  }
Enter fullscreen mode Exit fullscreen mode

Author Class

The Author Class doesn't need the Author Class, as the GetTitle will return the Name

public sealed class Author : ISearchResult
{
  public string? Name { get; set; }
  public string? Intro { get; set; }
  public string? AuthorHandler { get; set; }

  public string GetPublicUrl()
  {
    return "https://mydomain.conm/author/"  + AuthorHandler;
  }
  public string GetTitle()
  {
    return this.Name;
  }
  public string GetDescription()
  {
    return this.Intro;
  }
}
Enter fullscreen mode Exit fullscreen mode

Article Class

The article class implemented the GetAuthorName

public sealed class Article : ISearchResult
{
  public string? Title { get; set; }
  public string? FriendlyUrl { get; set; }
  public string? ShortIntro { get; set; }
  public Author AuthorInfo { get; set; }

  public string GetPublicUrl()
  {
    return "https://mydomain.com/article/" + FriendlyUrl;
  }
  public string GetTitle()
  {
    return this.Title;
  }

  public string GetDescription()
  {
    return this.ShortIntro;
  }
  public string GetAuthorName()
  {
    return " by " + this.AuthorInfo.Name;
  }
}
Enter fullscreen mode Exit fullscreen mode

The App

List<ISearchResult> _searchResults = new() { 
    new Author() { Name="Ernest Hemmingway", Intro= "Ernest Miller Hemingway was an American novelist, short-story writer, and journalist.", AuthorHandler="@ernesthemmingway" },

   new Author() { Name="Stephen King", Intro= "Stephen Edwin King is an American author of horror, supernatural fiction, suspense, crime, science-fiction, and fantasy novels. ", AuthorHandler="@stephenking" }

};

Article _article1 = new() { Title = "It", FriendlyUrl = "stephen-king-it", ShortIntro = "The story follows the experiences of seven children as they are terrorized by an evil entity that exploits the fears of its victims to disguise itself while hunting its prey" };
_article1.AuthorInfo.Name = "Stephen King";
_searchResults.Add(_article1);

//-- Show the results:
foreach(var _result in _searchResults)
{
    Console.WriteLine(_result.GetTitle() + _result.GetAuthorName());
}
Enter fullscreen mode Exit fullscreen mode

The Results

As you can see, even though we didn't implement the method GetAuthorName in the Author Class, the default is used inside the Interface (returning an empty string in our case)

Ernest Hemmingway
Stephen King
It by Stephen King
Enter fullscreen mode Exit fullscreen mode

Conclusion

Adding default behaviour to the Interface guarantees backward compatibility. Certainly when your interface is used by many classes and you need to add functionality to a few, like in the case of search results

Top comments (0)