Allowed Interface Members in C#
Mar 5, 2020 • 6 Minute Read
Introduction
In C#, the interface revolves around two main concepts: contract and inheritance. An interface is basically a syntactical contract that defines a guideline that classes inheriting a specific interface should follow. In simpler terms, the interface defines the what and the class deriving from it defines the how regarding the contract. Basically, interfaces provide a very similar functionality to abstract classes.
In this guide, we will walk through each part of this contract and see how they glue together to provide the functionality we all love and use today.
Interfaces
We have several different interface members:
- Properties
- Methods
- Events
- Indexers
These are like skeletons, and the deriving classes need to take care of filling them up with functionality.
In this demonstration we'll declare an interface called ServerInterface.
public interface ServerInterface
{
string name { get; set; }
string status { get; set; }
void restart();
void getStatus();
void start();
void stop();
event EventHandler statusChanged;
}
This interface declares two properties, name and status. It also declares four methods, restart,start,stop and getStatus. We have an event handler called statusChanged.
In order to enforce our contract, the class Server needs to inherit from this interface.
public class Server : ServerInterface
{
}
Due to the nature of the contract, we need to define the inherited members in our class. If we do not define them, we will get the following error from our compiler:
'Server' does not implement interface member 'ServerInterface.name'
'Server' does not implement interface member 'ServerInterface.type'
'Server' does not implement interface member 'ServerInterface.restart()'
'Server' does not implement interface member 'ServerInterface.status()'
'Server' does not implement interface member 'ServerInterface.statusChanged'
This explicitly tells us what we need to do. Let's look at the full-blown app and dissect it.
using System;
namespace Pluralsight
{
public interface ServerInterface
{
string name { get; set; }
string status { get; set; }
void restart();
void stop();
void start();
void getStatus();
event EventHandler statusChanged;
}
public class MyEventArgs : EventArgs
{
}
public class Server : ServerInterface
{
public string name { get; set; }
public string status { get; set; }
public event EventHandler statusChanged;
public Server(string Name)
{
name = Name;
status = "off";
}
public void getStatus()
{
Console.WriteLine($"THe server: {this.name} is {this.status}");
}
public void start()
{
if(this.status == "off") { Console.WriteLine($"Starting server: {this.name}"); this.status = "on"; }
else if(this.status == "on") { Console.WriteLine($"THe server: {this.name} is already started!"); }
else { Console.WriteLine($"The server is in an unknown state!"); }
}
public void stop()
{
if (this.status == "off") { Console.WriteLine($"The server: {this.name} is already stopped!"); }
else if (this.status == "on") { Console.WriteLine($"Stopping server: {this.name}"); this.status = "off"; }
else { Console.WriteLine($"The server is in an unknown state!"); }
}
public void restart() {
Console.WriteLine($"Event for restarting the server caught: {this.name}");
}
protected virtual void restart(MyEventArgs e)
{
statusChanged?.Invoke(this, e);
}
}
public class Interfacing
{
public static void Main()
{
Server a = new Server("Domain Controller");
a.start();
a.stop();
a.restart();
Console.ReadKey();
}
}
}
The output produced is as follows:
Starting server: Domain Controller
Stopping server: Domain Controller
Event for restarting the server caught: Domain Controller
All that needs to be done is to implement our part of the contract. We defined the specific methods, properties, and event handler. In the Main() function, our class inherited from the interface comes alone. We see the instance initialized, and then call the appropriate methods to perform their duties. The associated event with the restart action is also fired.
Interface vs. Abstract Class
While the concepts of an interface and an abstract class revolve around the same idea, it is important to lay out the facts and decide which one to use in which situation. While the interface cannot be instantiated, the abstract class can. Interfaces are way slower than abstract classes because of the lookup time for the appropriate signatures. Interfaces cannot have access specifiers by default, while abstract classes can. Interfaces can only have abstract methods, while abstract classes can have full implementation with non-abstract methods.
Conclusion
In this guide, we have learned how interface members can be implemented and how to use them to our own advantage in a live example. We have also learned to implement different members. We also looked at the difference between abstract classes and interfaces, and now we can decide which one to use in specific situations. I hope this guide has been informative to you and I would like to thank you for reading it.