C# equivalent of Java 8 Default Methods in Interface
Asked Answered
P

5

9

I heard that in Java 8 there is a flexibility of having function definitions in an Interface. I think we can have some default state with this feature in all the classes that are implementing such interface.

So, my question is do we have any such feature in C# as of today? Are there any plans from Microsoft on this regard ?

Phyl answered 19/12, 2016 at 15:39 Comment(6)
Do you mean like a base class?Plumper
@Plumper Having them in a base class is not the same thing semantically speaking.Stlaurent
#30322508Stlaurent
You achieve it today by using a base class (probably an abstract one), but there is no direct analog to the default interface methods that Java 8 supports. The CLR/IL technically allows for implementation of this feature, but I don't think it's being seriously considered for future C# releases.Pesthouse
They don't exist and I don't believe there is any plan for them to exist - the appropriate solution to such things is normally to declare a new interface for new functionality if the intention is to avoid breaking API changes. This idea never sat right with me - interfaces are for specifying contracts, not behaviour.Lightsome
factor out the base functionality into a base class that implements the interfaceEpisodic
K
5

Update

Default Interface Methods are a planned feature for C# 8.

Original Answer

C# doesn't have this exact feature, but Extension Methods solve the same problems that default methods were introduced to solve in Java.

In order to introduce LINQ-like functional methods to common collections in Java 8, the language designers wanted a way to add methods to interfaces like Iterable<>. After all, the .filter(a -> ...).map(a -> ...) syntax is much easier to read than map(filter(a ->...), a2 -> ...), which is what they'd have had to do if they just added utility methods. However, just adding a method signature to an interface would have been a breaking change because anybody who ever implemented that interface would suddenly have code that doesn't build in Java 8 unless they implemented the new methods. So they developed default implementation methods so that putting new methods on an existing interface wouldn't break existing code.

Years earlier, C# had solved the same problem by introducing Extension Methods. Rather than actually changing the interface itself, an Extension method just makes it easy to use a method (like .Where() and .Select() methods on an IEnumerable<>) defined in a utility class, as if it were actually on the target object.

The constraints put on Extension Methods and Default Implementations make them both very similar in scope. There are some advantages and disadvantages to each, which I won't go into here, but in essence they are just two different approaches to solve the same problem.

As it relates to your specific question: one of the downsides of Extension methods is that (being static) they break some of the best-practices of object-oriented code: it's possible to have naming collisions between them, and you can't override them reliably, for example. So it's usually best to avoid them unless you have a problem that cannot easily be solved in any other way. If you're just hoping to provide a default implementation of a method, you're typically better off using a base class instead, and expecting people to extend your base class.

I think you'd find that most Java experts would say the same thing about Default Implementations in Java. They weren't introduced prior to Java 8 because the prevailing wisdom is that interfaces are there to define what a thing is capable of doing, whereas classes are there to define how those things are done. Of course, you can always find a few smart people who think there's no good reason to have interfaces in the first place. But if you're using interfaces, it's presumably because you see value in defining a contract without providing implementation details. Default Implementations were introduced to solve a very specific backwards-compatibility problem, and if you can avoid that problem in the first place then there's not any really good reason I can see to use them.

Extension methods are at the same time more dangerous and more powerful, so there are some good uses for them outside of the backwards-compatibility problem, but they should still be used sparingly and only when other more object-oriented approaches won't work.

Kwashiorkor answered 21/12, 2016 at 4:7 Comment(8)
can you please elaborate how Extension Methods solve this problem. Do you think to implement the default functionality using Extension Methods on top of the those Interfaces, so that you can avail it later whenever you need ??. Please provide some example/scenario which will implement your thoughts on this regard.Phyl
In fact, extension are by far much better and much more flexible solutionNylanylghau
@JaganMohanReddy, did you read the link StriplingWarrior posted? It explains very well your scenario. There is an example of the interface and extension method, in which you can implement the same, you would implement in default method in javaNylanylghau
@JaganMohanReddy: I'm working to update my post with a better explanation. Please check back in a few minutes.Kwashiorkor
@DenisItskovich i read the referred link in that link in the General Guidelines sections they clearly recommended this "Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type". That's why i am asking for elaboration.Phyl
@JaganMohanReddy: Let me know if you have any questions after reading my update.Kwashiorkor
I'd say extension methods solve a very different problem to default implementations - they are designed to make static wrappers and utility methods read a bit nicer, while default implementations are designed to solve backward compatibility problems as you have mentioned.Lightsome
@AntP: Yes, but the reason that they needed to make static wrappers and utility methods read more nicely was to make LINQ possible. There's a reason that extension methods were introduced in the same version as lambda syntax. And that's the same reason that, in Java, default implementations were introduced in the same version as lambda syntax.Kwashiorkor
P
3

The official language proposal for default interface implementations in C# is documented here:

https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md

It is currently marked with status of "proposal".

With that said, there are numerous use cases for it which are altogether very strong. At present, it seems very likely to be approved as indicated by Mass Torgerson and Dustin Campbell in the video below. If so, it is almost certainly in line to be released with C#8.

https://channel9.msdn.com/Events/Build/2017/B8104

Around 53:00, the discussion begins and a demo is shown.

Pernambuco answered 14/5, 2017 at 2:5 Comment(0)
M
2

C# 8.0 will introduce the new feature of default interface implementations. This is useful when new methods are added to keep compatibility with existing implementations of the interface. It could also provide simple default implementations like shown in the following example:

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

    void Log(LogLevel level, string format, params object[] arguments)
    {
        Log(level, string.Format(format, arguments));
    }
}

New C# featues

Mendelevium answered 25/9, 2017 at 11:16 Comment(1)
Looks good, in fact, I don't understand why Java makes you write that annoying "default" keyword, when in reality it should be redundant.Yenta
P
1

I agree with the statements made in the comments so far - C# doesn't support this. As far as I know there's no plan to support this in C#, nor should it be supported. I disagree with Java 8 including this feature as well; I think it conflates interfaces and abstract base classes. As @AntP said in the comments, interfaces should be contracts (not to specify behavior).

Here are two possible designs that accomplish the same thing (and sorry about the hastily-drawn UML): enter image description here

Basically, point being you can either create an abstract base class that adds default implementations for all child classes, or you can have a base class for some of the child classes that implements the interfaces if that's what you're trying to do.

Obviously other designs are possible, this diagram is mostly just for the purposes of illustration.

Perpetual answered 19/12, 2016 at 16:15 Comment(2)
Not exactly the same thing. Interfaces support multiple inheritance and classes do not. You can implement multiple interfaces in your class, while some of that interfaces have default methods. Abstract class does not allow you to accomplish thisNylanylghau
@DenisItskovich No, it's not exactly the same thing, but I don't think that my basic point changes. In fact, if anything I think that that makes it an even worse idea to have default implementations in interfaces because of the Diamond Problem.Perpetual
M
1

C# does not supports this but I disagree with the comments which says interfaces should be contract not implementation. Because the default implementations are not for the sack of implementation it is for the sack of keeping clients free from implementing the newly updated interfaces and not let their old cold break if they do not use new methods introduced in new versions of the api they used before.

The default methods in java 8 implementation really helped solve real problems that arrived after updating api.

Malawi answered 21/12, 2016 at 4:2 Comment(2)
Everyone here understands what default methods are for, the point is that they are a poor way of maintaining backward compatibility and avoiding breaking API changes. Declaring new interfaces for new functionality is vastly better. If you really need default implementations it's a good indicator that you're approaching the problem wrong in the first place.Lightsome
I feel @mohammad-abu-hussen made a useful point, and am disappointed that it was downvoted. I don't agree that everyone understands what they are for. More than one of the motivations only impact most developers indirectly, by facilitating the evolution of a language or improving compatibility with other major languages and platforms. I think posts like this help people understand the context and reasoning behind high-level topics in a practical way, especially when they provide a relevant historical account.Pernambuco

© 2022 - 2024 — McMap. All rights reserved.