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:

if (m1 is IPerson) {

 IPerson p = (IPerson) m1;

 Console.WriteLine(p.Age());

 Console.WriteLine(p.Name);

 Console.WriteLine(p.DateofBirth);

}

if (m1 is IAddress) {

 IAddress a = (IAddress) m1;

 Console.WriteLine(a.Street);

 Console.WriteLine(a.Zip); Console.WriteLine(a.State());

}

if (e1 is IManager) {

 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:

IPerson p = m1 as IPerson;

if (p != null) {

 Console.WriteLine(p.Age());

 Console.WriteLine(p.Name);

 Console.WriteLine(p.DateofBirth);

}

IAddress a = m1 as IAddress;

if (a != null) {

 Console.WriteLine(a.Street);

 Console.WriteLine(a.Zip);

 Console.WriteLine(a.State());

}

Employee e1 = new Employee();

//---m is null after this statement---

IManager m = e1 as IManager;

if (m != null) {

 //...

}

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 virtual so that any other classes that inherit from the 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; }

 public virtual ushort Age() {

  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 {

 public override ushort Age() {

  return base.Age() + 1;

Вы читаете C# 2008 Programmer's Reference
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату