C# 8 supports default method implementations in interfaces. My idea was to inject a logging method into classes like this:
public interface ILoggable {
void Log(string message) => DoSomethingWith(message);
}
public class MyClass : ILoggable {
void MyMethod() {
Log("Using injected logging"); // COMPILER ERROR
}
}
I get a compiler error: "The name does not exist in the current context"
Is it impossible to use default method implementations in this way?
EDIT:
For the correct response regarding C# rules, see the accepted answer. For a more concise solution (the original idea of my question!) see my own answer below.
See the documentation at https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/default-interface-members-versions
That cast from SampleCustomer to ICustomer is necessary. The SampleCustomer class doesn't need to provide an implementation for ComputeLoyaltyDiscount; that's provided by the ICustomer interface. However, the SampleCustomer class doesn't inherit members from its interfaces. That rule hasn't changed. In order to call any method declared and implemented in the interface, the variable must be the type of the interface, ICustomer in this example.
So the method is something like
public class MyClass : ILoggable {
void MyMethod() {
ILoggable loggable = this;
loggable.Log("Using injected logging");
}
}
If you want to avoid clutter and repetitive casting you can add a single property which casts the type as the interface:
public class MyClass : ILoggable
{
ILoggable AsILoggable => (ILoggable)this;
void MyMethod()
{
AsILoggable.Log("Using injected logging");
}
}
But this is off. It seems wrong, regardless of how it's done. From the documentation:
The most common scenario is to safely add members to an interface already released and used by innumerable clients.
When there was some concern about having implementations in interfaces - which previously had none - this was the sentence that made sense of it. It's a way to add to an interface without breaking classes that already implement it.
But this question implies that we are modifying the class to reflect a change to an interface it implements. It's the exact opposite of the stated use case for this language feature.
If we're already modifying the class, why not just implement the method?
public void Log(string message) => DoSomethingWith(message);
When we add a default interface implementation, we provide an implementation to consumers of the interface - classes that depend on an abstraction.
If we depend on the default interface implementation from within the class that implements the interface, then a change to the interface becomes, in effect, a change to the internal implementation of the class. That's not what an interface is for. An interface represents external-facing behavior, not internal implementation.
It's as if the class is stepping outside of itself, looking back in at itself as an external consumer, and using that as part of its internal implementation. The class doesn't implement the interface, but it depends on it. That's weird.
I won't go so far as to say that it's wrong, but it feels like an abuse of the feature.
In CLR all interface member implementations are explicit, so in your code Log will be available in instances of ILoggable only, like it's recommended to do here:
((ILoggable)this).Log("Using injected logging")
The problem with the answers that cast the class to an interface is that it may or may not call the default interface method, depending on whether or not the class has implemented a method to override the default method.
So this code:
((ILoggable)this).Log(...)
ends up calling the default interface method, but only if there is no interface method defined in the class that overrides the default method.
If there is a method in the class that overrides the default method, then that is the method that will be called. This is usually the desired behavior. But, if you always want to call the default method, regardless of whether or not the implementing class has implemented its own version of that interface method, then you have a couple of options. One way is to:
Declare the default method as static. Don't worry, you will still be able to override it in a class that inherits from it.
Call the default method using the same type of syntax when calling a static method of a class, only substitute the interface name for the class name.
See this answer for a code example, along with an alternative way of calling a default interface method.
From reading an article about these default methods, I think you should try to upcast it to the interface:
((ILoggable)this).Log("Using injected logging")
I haven't checked it, just my thought according to this article.
Here are two alternative solutions to the ones already suggested:
First is to simply implement the interface method:
public class MyClass : ILoggable {
void MyMethod() {
Log("Using injected logging");
}
public void Log(string message) => ((ILog)this).Log(message);
}
This allows the method to be called directly, without having to write the cast to ILog each time.
Things to note:
this will make the method available on MyClass to outside users of it as well, where previously it was only available when an instance of MyClass is cast to / used as ILog
if you want to use 10 different methods from ILog in your class, you probably don't want to implement them all.
on the flipside, there are many scenarios where this is the "natural" / intended approach, primarily when MyClass extends the interface method with some custom logic (like ((ILog)this).Log("(MyClass): " + message) )
Second is using extension methods:
public static class LogExtensions
{
public static void Log<T>(this T logger, string message) where T : ILoggable => logger.Log(message);
}
public class MyClass : ILoggable {
void MyMethod() {
this.Log("Using injected logging");
}
}
This might be useful when ILoggable contains many methods / is implemented in many classes.
this still allows for Log to be overwritten in MyClass and the override to be called
essentially just syntactic sugar, shortening ((ILoggable)this) to this
The accepted answer and the other responses are correct.
However, what I wanted is a concise call of the Log method.
I achieved that with an extension method on the ILoggable interface:
public static class ILoggableUtils { // For extension methods on ILoggable
public static void Log(this ILoggable instance, string message) {
DoSomethingWith(message, instance.SomePropertyOfILoggable);
}
}
In this way, I can at least call this.Log(...); in my class instead of the ugly ((ILoggable)this).Log(...).
My solution is adding new abstract class between interface and it's implementations:
public interface ILoggable {
void Log(string message);
void SomeOtherInterfaceMethod();
}
public abstract class Loggable : ILoggable {
void Log(string message) => DoSomethingWith(message);
public abstract void SomeOtherInterfaceMethod(); // Still not implemented
}
public class MyClass : Loggable {
void MyMethod() {
Log("Using injected logging"); // No ERROR
}
public override void SomeOtherInterfaceMethod(){ // override modifier needed
// implementation
};
}
Related
Consider the code:
class ChildClass : BaseClass {
public void Method1() {} //some other method
}
abstract class BaseClass : IChildInterface {
public
virtual //<- If we add virtual so that this method can be overridden by ChildClass, we get StackOverflowException and DoWork() implementation in IChildInterface is never called.
void DoWork() {
//base class specific implmentation
((IChildInterface)this).DoWork(); //call into default implementation provided by IChildInterface
}
}
interface IChildInterface : IBaseInterface {
void IBaseInterface.DoWork() {
//implmentation
}
}
interface IBaseInterface {
void DoWork();
}
The problem is that if we mark DoWork() in BaseClass as virtual so that it can be overridden by child classes, it prevents it from calling into IChildInterface's default implementation of DoWork(), causing StackOverflowException.
If we remove virtual modifier from DoWork() in the BaseClass, everything works and the IChildInterface's default implementation of DoWork() is called.
Is such a behavior a bug, or by design?
Is there a way to make it possible for some child classes provide their own implementation of DoWork() (thus overriding BaseClass's implementation) but still being able to use IChildInterface's default implementation of DoWork()?
You're calling BaseClass.DoWork recursively which, if you're lucky, will result in a StackOverflowException. If the call was the last one in the method, you'd get an infinite recursion due to tail call optimizations. You'd end up with a core stuck at 100% until you killed the app.
This code :
public virtual void DoWork() {
((IChildInterface)this).DoWork(); by IChildInterface
}
Is identical to :
//That's the actual implementation of the interface method
public virtual void DoWork() {
DoWork();
}
The virtual keyword doesn't matter. You'd still get infinite recursion without it. Whether it exists or not, this line throws a StackOverflowException after a while :
new ChildClass().DoWork();
When you implemented BaseClass.DoWork that became the single implementation available to everyone, unless overridden by a child class.
Interfaces are not abstract classes, even in C# 8. A default method implementation is not an actual method. As the name says, it's a default implementation. It's used when there's no better implementation available. You can't call the default implementation when the method is already implemented in a class.
In fact, in almost every case you wouldn't expect the default method to be called. DIMs are called explicitly through the interface, the same way explicit interface implementations are used. Callers of the method expect the most-derived implementation to run, not the base or mid-level one.
Besides, even on previous C# versions you wouldn't expect casting to an interface to change which method is actually called. You'd expect that only with classes. To call a base class implementation you'd use the base keyword. The base class of BaseClass though is Object which doesn't have a DoWork method.
If you used :
void DoWork() {
base.DoWork();
}
You'd get a CS0117: 'object' does not contain a definition for 'DoWork'
Update
The C# design team has already though about this. This couldn't be implemented efficiently without runtime support and was cut i May 2019. Runtime optimizations is what makes DIM calls as cheap as other calls, without boxing etc.
The proposed syntax is a base(IMyInterface) call :
interface I1
{
void M(int) { }
}
interface I2
{
void M(short) { }
}
interface I3
{
override void I1.M(int) { }
}
interface I4 : I3
{
void M2()
{
base(I3).M(0) // What does this do?
}
}
As all methods inside interfaces are virtual by default the DoWork is virtual inside every each of these definitions/implementations you provided except the ChildClass. When you explicitly use DoWork of IChildInterface it uses BaseClass.DoWork implicitly which then uses ((IChildInterface)this).DoWork(); explicitly again. And so on. You have this loop that is never ending, hence you're getting the StackOverflow.
For the sake of future readers...
While the accepted answer provided by #Panagiotis is correct, in that there is no difference whether virtual modifier is present or not and StackOverflowExcpetion will occur in any case, I wanted to provide a concrete answer to the question that I settled on.
The whole point of implementing DoWork() in the IChildInterface as opposed to in a class was for code reuse and staying "DRY". Classes that implement IChildInterface should however be able to add their own functionality on top of what's provided by IChildInterface.
And therein lies a problem, as calling ((IChildInterface)this).DoWork(); from any class (abstract or not) that implements IChildInterface will result in infinite recursion. The only reasonable way out seems to use protected static members (as in fact is suggested in the Microsoft Docs):
class ChildClass : BaseClass {
public void Method1() {} //some other method
}
abstract class BaseClass : IChildInterface {
public virtual void DoWork() {
// Base class specific implementation here
// Then call into default implementation provided by IChildInterface:
// Instead of this: ((IChildInterface)this).DoWork();
// Use static implementation:
IChildInterface.DoWork(this);
}
}
interface IChildInterface : IBaseInterface {
protected static void DoWork(IChildInterface it){
// Implementation that works on instance 'it'
}
void IBaseInterface.DoWork() => IChildInterface.DoWork(this);
}
interface IBaseInterface {
void DoWork();
}
In the above solution we are staying "DRY" by still having a single (core) implementation of DoWork(), but it is located in a protected static member of the interface IChildInterface instead of being part of its inheritance hierarchy.
Then, as far as the inheritance hierarchy is concerned, all interfaces / classes deriving from / implementing IChildInterface could simply use IChildInterface.DoWork(this) to access the default implementation. This applies to the IChildInterface itself.
I have run into this situation many times, and have 'hacked' my way around the situation, but it seems it's a gap in my understanding.
Given the following code:
public class Foo
{
Bar barA = new BarA();
private void Bat() => barA.Baz();
}
public abstract class Bar
{
// Obviously this *can't* be private
private abstract Baz();
}
public class BarA : Bar
{
public void Run() => Baz();
// Again this can't be private
private override Baz() => DoSomething();
}
(caveat: I used expression bodied methods for sake of brevity in the example. Normally I would not unless there was a good reason to.)
Now, in the above example, my logic is that the Baz method needs to be defined by the concrete class, however the reason I want it private (and yes, I understand WHY it can't be, because it would be completely invisible/inaccessible to the concrete class), is logically, I do not want the concrete class to be able to call the method, merely define it.
The way to fix the code is to make the method protected, however, then the method becomes available to executable from within the concrete class.
Ultimately, I want an abstract/base class that handles internals of executing some code that is defined by the concrete class, however never available for the concrete class itself to call/execute. What is the flaw with that logic, or how should I be implementing that logic properly.
** EDIT: A concrete implementation **
Let's say for example this is part of a plugin system within a library (that I am creating, and another developer is implementing). Another part of the library uses derived classes that implement this abstract class (say it's a filter in image processing). The developer define's the method on what the filter does, however the abstract class (essentially handles the only processing that the defined filter provides), and yes the contract (interface) is made for the image processor so it doesn't (need to) know/care about implementation anyhow.
Like I said in the comments, what you're trying to do is a bit of a code smell. If your derived class needs to define how something in the base class works, then consider passing in an interface to the base. That way you're note exposing any public methods you don't need to and making things much more testable. You could do it something like this.
The interface and an implementation:
public interface IBaz
{
void Baz();
}
public class BigBaz : IBaz
{
public void Baz() => Console.WriteLine("Big Baz!");
}
Now your code slightly modified:
public abstract class Bar
{
private readonly IBaz _baz;
public Bar(IBaz baz)
{
_baz = baz;
}
public void DoBaz() => _baz.Baz();
}
public class BarA : Bar
{
//Here I'm passing into the constructor, but you may find it preferable
//to pass the IBaz directly as a parameter of the DoBaz method
public BarA() : base(new BigBaz())
{
}
}
Been reading all day on interfaces and abstract classes trying to get a grasp on them to better understand the amazon library I'm working with. I have this code:
using MWSClientCsRuntime;
namespace MarketplaceWebServiceOrders.Model
{
public interface IMWSResponse : IMwsObject
{
ResponseHeaderMetadata ResponseHeaderMetadata { get; set; }
}
and
namespace MWSClientCsRuntime
{
public interface IMwsObject
{
void ReadFragmentFrom(IMwsReader r);
string ToXML();
string ToXMLFragment();
void WriteFragmentTo(IMwsWriter w);
void WriteTo(IMwsWriter w);
}
}
My first questions is I thought Interfaces cannot contain fields, however they can contain properties usch as ResponseHeaderMetadata?
Second, in my main program I have this line of code:
IMWSResponse response = null;
with response being later used to store the information that amazon sends back after a method call is invoked. But what is the meaning behind setting a variable of an interface type to null?
Also, a interface can implement another interface? It isn't only classes that can implement interfaces, but interfaces themselves as well?
Pproperties can be present in interfaces since properties are actually methods - the use of T GetSomeValue() alongside void SetSomeValue(T value) became so common in other languages, that C# implements these as properties.
The meaning behind setting an interface member to null is the same as setting anyother property to null - since a property's set accessor is a method, it's like calling any other method on the interface. What null means where is up to the implementation.
Interfaces do not implement each other, since and interface cannot contain code and therefore is not implementing; Interface inheritance allows one to require one interface in another. A big example is IEnumerable<T>, which is so closely tied to IEnumerable that it inherits, thus meaning any class implementing IEnumerable<T> must also implement IEnumerable.
An interface is like a contractual agreement. By inheriting an interface from a class, you are saying, "I agree to implement all of the methods defined in this interface". So if you have an interface like this:
public interface IWorker {
void DoWork();
}
and you use that interface like this:
public class Employee : IWorker
{
// you are forced to implement this method
void DoWork {}
}
public class Contractor: IWorker
{
// you are forced to implement this method
void DoWork {}
}
By "inheriting" interfaces by other interfaces, you are simply agreeing to implement any methods in the other interfaces, like so (from MSDN):
interface IBase
{
void F();
}
interface IDerived: IBase
{
void G();
}
class C: IDerived
{
void IBase.F() {...}
void IDerived.G() {...}
}
class D: C, IDerived
{
public void F() {...}
public void G() {...}
}
You do not have to set a variable of an interface type to null, though you have the power to do so. The great thing about interfaces is that you are able to set a variable of the type of interface, to anything that "inherits" that interface.
Suppose an Interface I has two methods. For example Method1() and Method2().
A class A Implements an Interface I.
Is it possible for class A to implement only Method1() and ignore Method2()?
I know as per rule class A has to write implementation of both methods. I am asking if there any way to violate this rule?
You can avoid implementing it (a valid scenario) but not ignore it altogether (a questionable scenario).
public interface IFoo
{
void A();
void B();
}
// This abstract class doesn't know what to do with B(), so it puts
// the onus on subclasses to perform the implementation.
public abstract class Bar : IFoo
{
public void A() { }
public abstract void B();
}
No, there's no such concept in C# of optional interface members. If A implements I, then it must provide some implementation for all of I's members, even if the implementation does nothing or only throws an exception.
public class A : I
{
public void Method1()
{
// Do nothing.
}
public void Method2()
{
throw new NotImplementedException();
}
}
From a design perspective, why would you want to do this anyway in a statically typed language? Furthermore, why not just have two interfaces?
public interface I1 { void Method1(); }
public interface I2 { void Method2(); }
With your interfaces coded like this, you can have classes that implement one interface or the other, or both, or neither. To me, this makes more sense anyway.
UPDATE 2018-06-13
The C# lang Git Hub has a proposal in progress for default interface methods. In short, the interface developer would be able to provide an implementation for a method or methods in the interface itself, and the developer using the interface on their class or struct would not have to implement those methods explicitly. Not exactly what the OP was asking about, but potentially useful.
You must implement all methods of the interfaces your class inherits from. There is no way around that. But you can use explicit interface implementation to hide the method.
That way a user doesn't see the method on a variable that has the class as type, but when he casts to the interface he can call the method.
class A : I
{
void I.Method2()
{
throw new NotSupportedException();
}
}
then
A a;
a.Method2(); //doesn't compile
I i = a;
i.Method2(); //works
If the class A is only an abstract base class, you can also use an abstract method to implement the interface, leaving the concrete implementation to the derived classes.
No, there's not.
But you can code :
public void Method2(){
throw new NotImplementedException();
}
That will inform the application that this method cannot be called from this instance.
Yes if I was a class, but No if it's an interface.
We define interface as below:
interface IMyInterface
{
void MethodToImplement();
}
And impliments as below:
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
}
instead of creating a interface , why can we use the function directly like below :-)
class InterfaceImplementer
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
}
Any thoughts?
You are not implementing the interface in the bottom example, you are simply creating an object of InterfaceImplementer
EDIT: In this example an interface is not needed. However, they are extremely useful when trying to write loosely coupled code where you don't have to depend on concrete objects. They are also used to define contracts where anything implementing them has to also implement each method that it defines.
There is lots of information out there, here is just a brief intro http://www.csharp-station.com/Tutorials/Lesson13.aspx
If you really want to understand more about interfaces and how they can help to write good code, I would recommend the Head First Design Patterns book. Amazon Link
instead of creating a interface , why
can we use the function directly like
below
Are you asking what the point of the interface is?
Creating an interface allows you to decouple your program from a specific class, and instead code against an abstraction.
When your class is coded against an interface, classes that use your class can inject whichever class they want that implements this interface. This facilitates unit testing since not-easily-testable modules can be substituted with mocks and stubs.
The purpose of the interface is for some other class to be able to use the type without knowing the specific implementation, so long as that type conforms to a set of methods and properties defined in the interface contract.
public class SomeOtherClass
{
public void DoSomething(IMyInterface something)
{
something.MethodToImplement();
}
}
public class Program
{
public static void Main(string[] args)
{
if(args != null)
new SomeOtherClass().DoSomething(new ImplementationOne());
else
new SomeOtherClass().DoSomething(new ImplementationTwo());
}
}
Your example doesn't really follow that pattern, however; if one that one class implements the interface, then there really isn't much of a point. You can call it either way; it just depends on what kind of object hierarchy you have and what you intend to do for us to say whether using an interface is a good choice or not.
To sum: Both snippets you provide are valid code options. We'd need context to determine which is a 'better' solution.
Interfaces are not required, there is nothing wrong with the last section of code you posted. It is simply a class and you call one of it's public methods. It has no knowledge that an interface exists that this class happens to satisfy.
However, there are advantages:
Multiple Inheritance - A class can only extend one parent class, but can implement any number of interfaces.
Freedom of class use - If your code is written so that it only cares that it has an instance of SomethingI, you are not tied to a specific Something class. If tomorrow you decide that your method should return a class that works differently, it can return SomethingA and any calling code will not need to be changed.
The purpose of interfaces isn't found in instantiating objects, but in referencing them. Consider if your example is changed to this:
static void Main()
{
IMyInterface iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
Now the iTmp object is of the type IMyInterface. Its specific implementation is InterfaceImplementer, but there may be times where the implementation is unimportant (or unwanted). Consider something like this:
interface IVehicle
{
void MoveForward();
}
class Car : IVehicle
{
public void MoveForward()
{
ApplyGasPedal();
}
private void ApplyGasPedal()
{
// some stuff
}
}
class Bike : IVehicle
{
public void MoveForward()
{
CrankPedals();
}
private void CrankPedals()
{
// some stuff
}
}
Now say you have a method like this somewhere:
void DoSomething(IVehicle)
{
IVehicle.MoveForward();
}
The purpose of the interface becomes more clear here. You can pass any implementation of IVehicle to that method. The implementation doesn't matter, only that it can be referenced by the interface. Otherwise, you'd need a DoSomething() method for each possible implementation, which can get messy fast.
Interfaces make it possible for an object to work with a variety of objects that have no common base type but have certain common abilities. If a number of classes implement IDoSomething, a method can accept a parameter of type IDoSomething, and an object of any of those classes can be passed to it. The method can then use all of the methods and properties applicable to an IDoSomething without having to worry about the actual underlying type of the object.
The point of the interface is to define a contract that your implementing class abides by.
This allows you to program to a specification rather than an implementation.
Imagine we have the following:
public class Dog
{
public string Speak()
{
return "woof!";
}
}
And want to see what he says:
public string MakeSomeNoise(Dog dog)
{
return dog.Speak();
}
We really don't benefit from the Interface, however if we also wanted to be able to see what kind of noise a Cat makes, we would need another MakeSomeNoise() overload that could accept a Cat, however with an interface we can have the following:
public interface IAnimal
{
public string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "woof!";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "meow!";
}
}
And run them both through:
public string MakeSomeNoise(IAnimal animal)
{
return animal.Speak();
}