Declaring a member function in an interface

First off, I'm pretty new to C #. I would like the interface to declare a member function, as in the following code snippet

interface IMyInterface { void MyAction() { // do stuff depending on the output of function() } void Function(); } 

here Function is purely virtual and should be implemented by IMyInterface . I could use an abstract class instead of an interface, but then I could not inherit from other classes ... Say, for example, that MyAction recursively looks for a directory for files and applies Function to any file found to make my example clear.

How to change my project to overcome the limitation that interfaces cannot implement classes?

Edit: In C ++, I would do to use templates as such

 template<class A> static void MyAction(const A& a) { // do stuff depending on the output of A::Function() }; class MyClass { void Function(); }; 

I was wondering if there is an elegant way to do this using interfaces in C #.

+7
source share
9 answers

In C #, you don't have multiple inheritance. You can get around this limitation using composition .

Define your interface as follows ( Function does not need to be defined here):

 public interface IMyInterface { void MyAction(); } 

Declare an abstract class with abstract Function and implement this interface:

 public abstract class MyInterfaceBase : IMyInterface { public void MyAction() { // Do stuff depending on the output of Function(). Function(); } protected abstract void Function(); } 

From this abstract class you can get a concrete implementation. This is not your β€œfinal” class, but it will be used to create it.

 public class ConcreteMyInterface : MyInterfaceBase { protected override void Function() { Console.WriteLine("hello"); } } 

Now let me come to your "final", compiled class. It will be obtained from SomeBaseClass and implements IMyInterface by integrating the ConcreteMyInterface functionality:

 public class SomeBaseClass { } public class MyComposedClass : SomeBaseClass, IMyInterface { private readonly IMyInterface _myInterface = new ConcreteMyInterface(); public void MyAction() { _myInterface.MyAction(); } } 

UPDATE

In C #, you can declare local classes. This is approaching multiple inheritance, as you can get everything in your composition.

 public class MyComposedClass : SomeBaseClass, IMyInterface { private readonly IMyInterface _myInterface = new ConcreteMyInterface(); public void MyAction() { _myInterface.MyAction(); } private class ConcreteMyInterface : MyInterfaceBase { protected override void Function() { Console.WriteLine("hello"); } } } 
+8
source

The only way to directly handle this will be to use an abstract class, because the interface cannot contain any β€œlogic” of any form and is simply a contract.

However, one alternative would be to create an interface and a static class. Then you can put your logic in the extension method using the interface.

 public interface IMyInterface { void Function(); } public static class MyInterfaceExtensions { public static void MyAction(this IMyInterface object) { // use object.Function() as needed } } 

The main disadvantages here are more types that reduce maintainability and lack of detection.

+10
source

You can define MyAction as an extension method :

 public interface IMyInterface { void Function(); } public static class MyInterfaceExtensions { public static void MyAction(this IMyInterface obj) { obj.Function(); } } 

Example:

 public class HelloWorld : IMyInterface { public void Function() { Console.WriteLine("Hello World"); } public static void Main(string[] args) { new HelloWorld().MyAction(); } } 

Output:

  Hello world 
+6
source

Interfaces cannot implement any behavior that they simply contract. If you want to implement some logic when defining a contract, you can use an abstract class.

+2
source

For this purpose. you need to define an abstract class. You can provide a default implementation or leave the implementation a derived class.

If a derived class wants to override a thing, it can always do it. This gives them the opportunity to use the database along with the changes they want to override.

+2
source

Declare the function interface (signature and return types) in the interface. Then create an abstract class that is defined to implement this interface and implements the default base implementation in the abstract class. Then create other concrete classes that inherit from the abstract class, but if necessary redefine the base implementation of abstract classes with a different implementation.

+1
source

This problem is best solved by dividing external behavior; MyAction in this case, from an internal implementation; MyFunction .

It should be understood here what should be part of the interface / contract between this class and others, and what should be part of the implementation of this contract.

Here, a contract is determined between this object and its consumers;

 interface IMyInterface { void MyAction(); } 

Now, the base class that implements this interface, and also provides the implementation of certain behavior;

 abstract class BaseClass : IMyInterface { public void MyAction() { // do some commmon action // call derived implementation to deal with the outcome } protected abstract MyFunvoid ction(); } 

And finally, a specific implementation that deals with MyFunction results in a specific way;

 class ConcreteClass : BaseClass { protected override void MyFunction() { // concrete iomplementation here } } 
+1
source

An interface is a contract and cannot contain an implementation.

From your statement above:

I could use an abstract class instead of an interface, but then I could not inherit other classes

I believe that you click "why the C # question does not support multiple inheritance".

Here is a CodeProject article on Simulated Multiple Inheritance for C # . You must follow this pattern to achieve a workaround to a simple C # inheritance model.

0
source

This is the suggested feature for C # 8.0:

 interface IA { void M() { WriteLine("IA.M"); } } class C : IA { } // OK IA i = new C(); iM(); // prints "IA.M"` 

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

0
source

All Articles