You can now access members (the Age()
method and Name
and DateofBirth
properties) through p
:
Console.WriteLine(p.Age());
Console.WriteLine(p.Name);
Console.WriteLine(p.DateofBirth);
Likewise, you can cast the m1
to the IAddress
interface and then assign it to a variable to of type IAddress
:
//---cast to IAddress---
IAddress a = (IAddress) m1;
Console.WriteLine(a.Street);
Console.WriteLine(a.Zip);
Console.WriteLine(a.State());
Note that instead of creating an instance of a class and then type casting it to an interface, like this:
Manager m2 = new Manager();
IPerson p = (IPerson) m2;
You can combine them into one statement:
IPerson p = (IPerson) new Manager();
The is and as Operators
Performing a direct cast is safe only if you are absolutely sure that the object you are casting implements the particular interface you are trying to assign to. Consider the following case where you have an instance of the Employee
class:
Employee e1 = new Employee();
The Employee
class implements the IPerson
and IAddress
interfaces. And so if you try to cast it to an instance of the IManager
interface, you will get a runtime error:
//---Error: Invalid cast exception---
IManager m = (IManager) e1;
To ensure that the casting is done safely, use the is
operator. The is
operator checks whether an object is compatible with a given type. It enables you to rewrite the casting as:
IPerson p = (IPerson) m1;
Console.WriteLine(p.Age());
Console.WriteLine(p.Name);
Console.WriteLine(p.DateofBirth);
}
IAddress a = (IAddress) m1;
Console.WriteLine(a.Street);
Console.WriteLine(a.Zip); Console.WriteLine(a.State());
}
IManager m = (IManager) e1;
}
Using the is
operator means that the compiler checks the type twice — once in the is
statement and again when performing the actual casting. So this is actually not very efficient. A better way would be to use the as
operator.
The as
operator performs conversions between compatible types. Here's the preceding casting rewritten using the as
operator:
Console.WriteLine(p.Age());
Console.WriteLine(p.Name);
Console.WriteLine(p.DateofBirth);
}
Console.WriteLine(a.Street);
Console.WriteLine(a.Zip);
Console.WriteLine(a.State());
}
Employee e1 = new Employee();
//...
}
If the conversion fails, the as operator returns null
, so you need to check for null
before you actually use the instance of the interface.
Overriding Interface Implementations
When implementing an interface, you can mark any of the methods from the interface as virtual
. For example, you can make the Age()
method of the Employee
class Employee
class can override its implementation:
public interface IPerson {
string Name { get; set; }
DateTime DateofBirth { get; set; }
ushort Age();
}
public class Employee : IPerson {
public string Name { get; set; }
public DateTime DateofBirth { get; set; }
return (ushort)(DateTime.Now.Year - this.DateofBirth.Year);
}
}
Suppose there is a new class called Director
that inherits from the Employee
class. The Director
class can override the Age()
method, like this:
public class Director : Employee {