Interface in C#
Interface in C# has been introduced to implement multiple inheritance, which is not possible using the classes. You can go through my article why .NET does not support Multiple inheritance. Using interfaces, we can implement two or more interface contract to a single class. I have said the word contract here as it is mandatory for the derived class to implement all the functions implemented by the interface.
CodeProject
You can learn about type safety and type conversion here.
Defining an Interface
An interface is a logical group of some desired set of method signatures with the help of which we want to achieve some functionality. Since it is a set of methods, that is why events as well as properties (indexers also) can also be contained by an interface. But interface cannot define any constructor methods and neither they can define any instance fields and also it cannot contains any static members. Interface is a reduced version of multiple inheritance. I have mentioned the reduced version as the class implementing the multiple interfaces need to implement all the methods declared in the deriving classes. One of the main features of the interface is that it allows the instance of the derived types to be used wherever an interface is being used, which would be useful to understand why interfaces are used. In need to define an interface, we use the interface
keyword and its set of instance method signatures. And generally, it is advised to start the interface with I letter. One of the examples of Interface
is as shown below:
public interface IEmployee
{
string DoWork();
}
The above code contains a method signature named DoWork()
.
Before going further, I want to emphasize how CLR treats the interface. For CLR interface is just like defining a class or rather it treats interface definition as type definition. These words can be confirmed by the fact that reflection can be used to query the features of the interface type as shown in the below code.
MethodInfo[] methodInfos = Type.GetType("InterfacesInCSharp.IEmployee").GetMethods
(BindingFlags.Public | BindingFlags.Instance);
The interface functions need to be public
in the derived class implementation which is a condition imposed by the C# compiler.
Interface Implementation
- As I have already defined an interface
IEmployee
in the above code snippet, now if I want to implement the interface to my class SoftwareEngineer
as shown below:
public class Engineer:IEmployee
{
}
If I execute the above code, I will get an compile time error stating that “’InterfacesInCSharp.Engineer
’ does not implement interface member ‘InterfacesInCSharp.IEmployee.DoWork()
’” which is obvious as CLR expects each and every function of interface to be defined in the implementing class. The correct implementation of the above code would be as shown below:
public class Engineer:IEmployee
{
#region IEmployee Members
public string DoWork()
{
return string.Empty;
}
#endregion
}
As we can see from the above code, the signature of the DoWork()
method in the Engineer
class is the same as the signature of the method in the (IEmployee
)Interface.
- Just like types interfaces can be defined at the file scope or can be nested within a type as shown below or at the file scope.
public class Engineer : IEmployee
{
public string DoWork()
{
return string.Empty;
}
public interface IMyWork
{
}
}
- Interface can only “inherit” from other interface. Suppose we want to extend the implementation of an interface in some part of our project without disturbing the already created interface, in that we can create a new interface and inherit it into new interface as shown below:
public interface IHuman
{
void SocialAnimal();
}
public interface IEmployee : IHuman
{
string DoWork();
}
public class Engineer : IEmployee
{
public string DoWork()
{
return string.Empty;
}
public void SocialAnimal()
{
}
}
Creating a Variable for the Interface Type
As soon as we are done with the creation and implementation of the interfaces, we need to create the variables for them, so that implementing classes can be used to do the desired functionality. We can always create the variable of type of the implementing class as shown in the following code for the classes defined in previous snippet.
static void Main(string[] args)
{
Engineer eng = new Engineer();
}
But it is always suggested to create the variable of interface type containing the reference of the implementing class as shown below:
static void Main(string[] args)
{
IEmployee eng = new Engineer();
}
And this concept can be implemented by having a loosely coupled design in the application. Now suppose I want my IEmployee
to do work, in that case I can always create a function which takes a parameter of type IEmployee
and not Engineer
type.
public void DoWork(IEmployee emp)
{
emp.DoWork();
}
Value Types Implementing Interfaces
As discussed previously, reference types or classes are not the only one which can implement interfaces. Value types can also implement the zero or more interfaces. The example of which can be shown in the below code snippet.
public struct Employee : IEmployee
{
public string DoWork()
{
return string.Empty;
}
}
In the above code, I have defined a structure Employee
which implements the IEmployee
interface which I have defined in the previous code snippet.
Now, when we create a variable of the interface containing the reference of the a values type, CLR boxes the values type instance which is a must as interface variable is a reference that must point to an object on the heap so that CLR can examine the object’s type object pointer to determine exact type of the object which is not possible with the case of value types. Now whenever the interface variable is used to call any method of the value type, the object’s boxed type pointer is followed by CLR to find the type object’s method table in order to call the proper method.
Interface Methods are Virtual !!
Yes, you read it right; the interface methods are defined as virtual and sealed by the C# compiler. This thing can be checked by getting into IL code of the interface by using ILDASM.exe. Since the methods are also marked as sealed by compiler, we cannot override the methods in the derived classes. But if you want to override the method’s implementation in some of the derived class, we have to mark the methods as virtual explicitly as shown in the code below:
public class Engineer : IEmployee
{
public virtual string DoWork()
{
return string.Empty;
}
}
And a class inheriting from the Engineer
class:
public class JuniorEngineer:Engineer
{
public override string DoWork()
{
return string.Empty;
}
}
Explicit Implementation of Interfaces
Suppose I have two interfaces containing the same method signatures as shown below:
interface Interface1
{
void DoSomething();
}
interface Interface2
{
void DoSomething();
}
I have a scenario in which I have to implement both of these interfaces in the same class, in that case we will go for explicit interface implementation as shown below:
public class ExplicitImplentation : Interface1, Interface2
{
void Interface1.DoSomething()
{
}
void Interface2.DoSomething()
{
}
}
In explicit implementation, both the functions are private
and can be accessed by type casting the reference of the class to particular interface as shown below:
ExplicitImplentation exp = new ExplicitImplentation();
Interface1 int1 = exp;
int1.DoSomething();
Interface2 int2 = exp;
int2 = exp;
int2.DoSomething();
I hope you have enjoyed reading the article and learned something new in this article, and share this with your friends. Kindly let me know your thoughts about the article.
The post Interfaces walk through appeared first on Dot Net For All.