Default implementation of a method for C# interfac

2019-03-11 21:52发布

问题:

Is it possible to define an interface in C# which has a default implementation? (so that we can define a class implementing that interface without implementing that particular default method).

I know extension methods (as explained in this link for example). But that is not my answer because having a method extension like the following, the compiler still complains about implementing MyMethod in MyClass:

public interface IMyInterface
{
    string MyMethod();
}

public static class IMyInterfaceExtens
{
    public static string MyMethod(this IMyInterface someObj)
    {
        return "Default method!";
    }
}

public class MyClass: IMyInterface
{
// I want to have a default implementation of "MyMethod" 
// so that I can skip implementing it here
}

I am asking this because (at least as far as I understand) it is possible to do so in Java (see here).

PS: having an abstract base class with some method is also not my answer simply because we don't have multiple inheritance in C# and it is different from having a default implementation for interfaces (if possible!).

回答1:

I develop games so I often want to have common function for all implementations of an interface but at the same time allow each implementation to do its own thing as well, much like a subclass' virtual / override methods would function.

This is how I do it:

public class Example
{
    void Start()
    {
        WallE wallE = new WallE();
        Robocop robocop = new Robocop();

        // Calling Move() (from IRobotHelper)
        // First it will execute the shared functionality, as specified in IRobotHelper
        // Then it will execute any implementation-specific functionality,
        // depending on which class called it. In this case, WallE's OnMove().
        wallE.Move(1);

        // Now if we call the same Move function on a different implementation of IRobot
        // It will again begin by executing the shared functionality, as specified in IRobotHlper's Move function
        // And then it will proceed to executing Robocop's OnMove(), for Robocop-specific functionality.
        robocop.Move(1);

        // The whole concept is similar to inheritence, but for interfaces.
        // This structure offers an - admittedly dirty - way of having some of the benefits of a multiple inheritence scheme in C#, using interfaces.
    }

}

public interface IRobot
{
    // Fields
    float speed { get; }
    float position { get; set; }

    // Implementation specific functions.
    // Similar to an override function.
    void OnMove(float direction);
}

public static class IRobotHelper
{
    // Common code for all IRobot implementations. 
    // Similar to the body of a virtual function, only it always gets called.
    public static void Move(this IRobot iRobot, float direction)
    {
        // All robots move based on their speed.
        iRobot.position += iRobot.speed * direction;

        // Call the ImplementationSpecific function
        iRobot.OnMove(direction);
    }
}

// Pro-Guns robot.
public class Robocop : IRobot
{
    public float position { get; set; }

    public float speed { get; set;}

    private void Shoot(float direction) { }

    // Robocop also shoots when he moves
    public void OnMove(float direction)
    {
        Shoot(direction);
    }
}

// Hippie robot.
public class WallE : IRobot
{
    public float position { get; set; }

    public float speed { get; set; }

    // Wall-E is happy just moving around
    public void OnMove(float direction) { }
}


回答2:

C# v8 will start allowing concrete method implementation in interfaces as well. This will allow your concrete implementation classes to not break when you change the interfaces being implemented in future.

So something like this will be possible in the next language version:

interface IA
{
    void NotImplementedMethod();
    void M() { WriteLine("IA.M"); } //method definition present in the interface
}

Please refer to this GitHub issue # 288. Also Mads Torgersen talks about this upcoming feature at length in this channel 9 video.

Note: Current version of C# language in RTM state is v7 at the time of writing this answer.



回答3:

Short Answer:

No, you cannot write implementation of method in interfaces.

Description:

Interfaces are just like contract ,so that the types that will inherit from it will have to define implementation, if you have a scenario you need a method with default implementation, then you can make your class abstract and define default implementation for method which you want.

For Example:

public abstract class MyType
{
    public string MyMethod()
    {
      // some implementation
    }

    public abstract string SomeMethodWhichDerivedTypeWillImplement();
}

and now in Dervied class:

public class DerivedType : MyType
{
  // now use the default implemented method here
}

UPDATE (C# 8 will have support for this):

C# 8 will allow to have default implementation in interfaces



回答4:

Not directly, but you can define an extension method for an interface, and then implement it something like this

public interface ITestUser
{
    int id { get; set; }
    string firstName { get; set; }
    string lastName { get; set; }

    string FormattedName();
}

static class ITestUserHelpers
{
    public static string FormattedNameDefault(this ITestUser user)
    {
        return user.lastName + ", " + user.firstName;
    }
}

public class TestUser : ITestUser
{
    public int id { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }

    public string FormattedName()
    {
        return this.FormattedNameDefault();
    }
}

Edit* It is important that the extension method and the method that you are implementing are named differently, otherwise you will likely get a stackoverflow.



回答5:

As a newbe C# programmer I was reading through this topic and wondered if the following code example could be of any help (I don't even know if this is the proper way to do it). For me it allows me to code default behavior behind an interface. Note that I used the generic type specifiction to define an (abstract) class.

namespace InterfaceExample
{
    public interface IDef
    {
        void FDef();
    }

    public interface IImp
    {
        void FImp();
    }

    public class AbstractImplementation<T> where T : IImp
    {
        // This class implements default behavior for interface IDef
        public void FAbs(IImp implementation)
        {
            implementation.FImp();
        }
    }

    public class MyImplementation : AbstractImplementation<MyImplementation>, IImp, IDef
    {
        public void FDef()
        {
            FAbs(this);
        }
        public void FImp()
        {
            // Called by AbstractImplementation
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyImplementation MyInstance = new MyImplementation();

           MyInstance.FDef();
        }
    }
}


标签: c# oop interface