Questions tagged [default-interface-member]

A default interface member is a feature introduced in C# 8 which allows an interface to declare a member with a body. Classes which implement the interface are not required to override a default method. Use this tag for questions relating to C# 8's default interface members

Default interface members were introduced in . They are similar to Java's feature.

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.

Default interface members help in the following scenarios :

  • Interface versioning
  • Interoperation with APIs targeting Android (Java) and iOS (Swift), which support similar features.
  • To implement without requiring multiple inheritance, similar to PHP and Scala traits. Java 8 and later also supports traits through default interface methods
  • Code Reuse in structs (Thanks Eirik Tsarpalis!)

Interface Versioning

This example is adapted from Mads Torgersen's article on Default implementations in interfaces:

Let’s say that we offer the following interface:

interface ILogger
{
    void Log(LogLevel level, string message);
}

And a class that implements it :

class ConsoleLogger : ILogger
{
    public void Log(LogLevel level, string message) { ... }
}

With default members, the interface can be modified without breaking ConsoleLogger :

interface ILogger
{
    void Log(LogLevel level, string message);
    void Log(Exception ex) => Log(LogLevel.Error, ex.ToString());
}

The ConsoleLogger 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’s default implementation is just called:

public static void LogException(ConsoleLogger logger, Exception ex)
{
    ILogger ilogger = logger; // Converting to interface
    ilogger.Log(ex);          // Calling new Log overload
}

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.

Traits

In an imaginary game, items may inherit from a GameItem class :

public class GameItem    {    }

Let's assume that a potion doesn't have a location, nor does it move :

public class Potion:GameItem{}

A rock may have a location :

public interface ILocatable
{
    public (double x,double y) Location{get;set;}
}

public class Rock:GameItem,ILocatable
{
    public (double x,double y) Location{get;set;}
}

A player or monster can also move. Without traits, one possible solution would be to add the ability to move to GameItem or introduce an intermediate abstract class with that functionality. Modifying GameItem would also affect Rock while the abstract class would introduce a relation that probably isn't appropriate.

This can be solved with the IMovable trait, which can be applied to any type that has a Location property :

public interface IMovable
{
    public abstract (double x,double y) Location{get;set;}
    void Move(double angle,double speed)
    {              
          var x=Location.x + speed*Math.Sin(angle);
          var y=Location.y + speed*Math.Cos(angle);
          Location=(x,y);
    }
}    

That trait can be applied to any class as long as it has a matching Location property:

public class Player:GameItem,ILocatable,IMovable
{
    public (double x,double y) Location{get;set;}
}

public class Monster:GameItem,ILocatable,IMovable
{
    public (double x,double y) Location{get;set;}
}

Trait Example - Reading settings in a container environment

In container-based or serverless applications, one of the most common ways to distribute settings is through environment variables. DIMs can be used to create a trait that retrieves a specific environment variable each time it's called, eg :

interface IGithubSettings
{
    public string CurrentToken  => Environment.GetEnvironmentVariable("GitHubToken");
}

References :

61 questions
3
votes
0 answers

Is this a bug in visual studio 2019? I'm getting a error CS0570 for a program while debugging

Consider the following interface and a dummy class that implements it. interface I { System.Collections.Generic.IEnumerable M() { var x = default(T); yield return x; } } public class C : I { public…
Michael B
  • 7,512
  • 3
  • 31
  • 57
3
votes
0 answers

How to call default interface implementation correctly?

the "override" of default interface impl of AcceptChanges does not call the default interface impl after casting this to interface type containing the default interface implementation. Why? public interface IItemViewModel1 { void AcceptChanges()…
CleanCoder
  • 2,406
  • 1
  • 10
  • 35
3
votes
2 answers

In C# 8.0 is there a way to expose default member implementation on the class?

In C# 8.0 interfaces can have default implementations for some members. These implementations are explicit meaning that they are inaccessible through the class instance and we must cast to the interface type to call them. Is there a way to expose…
Stilgar
  • 22,354
  • 14
  • 64
  • 101
3
votes
1 answer

Is this public - but abstract - interface method expected behavior?

I recently discovered (thanks to a broken build targeting core 2.2) that this is now legal in C# 8 public interface ISimple { public string Simon { get; } } ISimple is an interface, Simon has no implementation, but the public keyword is…
Binary Worrier
  • 50,774
  • 20
  • 136
  • 184
3
votes
0 answers

C# 8.0 default interface implementations base syntax/explicit invocations

I've been messing around with the default interface implementations. Figured you have to de a downcast to the interface type to use a default method implementation. I also found a bunch of notes on another syntax, I can't find if this is already…
c2619813
  • 31
  • 1
3
votes
2 answers

Why C#8 Default implementations of interface members will report an error

Why C#8 Default implementations of interface members will report an error? public interface Logger { void Info(string message); void Error(string message); // C#8 Default implementations of interface void Warn(string message) { …
3
votes
2 answers

Calling C# interface default method from implementing struct without boxing

The only thing I can think of is as follows, which is far from ideal: interface IBar { void Foo() => Console.WriteLine("Hello from interface!"); } struct Baz : IBar { // compiler error void Test1() => this.Foo(); // IIRC this will…
Velocirobtor
  • 188
  • 7
3
votes
0 answers

When to use abstract class over an interface with default implementations?

C# 8 adds the option for default method implementation in interfaces, meaning a method CAN be defined in the interface. In a situation when I DON'T need a default constructor, nor inherited fields in the derived classes, what should I default to: An…
2
votes
1 answer

Why constant defined in an interface cannot be accessed without Interface name in the implemented class?

We have the interface and the implementing class: pubic interface IStackContainer { const string DefaultStack = "default"; } public class StackContainer : MyBaseStackContainer, IStackContainer{ protected internal string Stack { …
Eugene Maksimov
  • 1,504
  • 17
  • 36
2
votes
1 answer

C# 8 Interface Default Implementation

Dear editors, Why you mark this question as Opinion-based? I have no opinion, I just asked a basic question. I have a basic confusion with C# 8 Interface implementation concept, As you know Interface is not more than a Contract, Why we need to…
Saeid Babaei
  • 481
  • 2
  • 16
2
votes
1 answer

C# 8 Default implementation and Dependency Inversion

With C#8 Microsoft introduced Default Implementation for interface methods. It's still a fairly new feature and there seem to be many concerned bloggers writing about this. What I'm wondering is if Default Implementation has the potential to be a…
2
votes
2 answers

C# 8 default interface implementation and inheritance

I want to use C# 8 default interface implementation to face a performance issue in my code. Actually, I have this intefaces : public interface IDataAdapter {} public interface IDataAdapter : IDataAdapter { void Insert(T value); } I actually…
cdie
  • 4,014
  • 4
  • 34
  • 57
1
vote
1 answer

How to call default implementation of overridden interface method in C# 8.0?

I'm starting to use C# 8.0 and default interface implementations. According to the official C# documentation, we can call the default implementation of an interface method from another object derived from it using the syntax…
1
vote
1 answer

Define protected abstract interface method as abstract in abstract class

I have an interface like this interface IFoo { protected abstract int Compute(); int ComputeValue() { return Compute(); } } The idea being that Compute computes some value and ComputeValue maybe does some checks and then…
1
vote
2 answers

Multiple Interface Inheritance with method body

Suppose I have these 2 Interfaces. public interface IMath2 { int GetSum(int x, int y) { return x + y; } } public interface IMath1 { int GetSum(int x, int y) { return x + y; } } and One class with inherit…
Darshit Gandhi
  • 121
  • 1
  • 7