Принципы объектно-ориентированного программирования

         

Запрос о реализации интерфейса с помощью is



Запрос о реализации интерфейса с помощью is

В примере InterfaceApp вы видели код, использованный для приведения объекта (MyControl) к одному из реализованных в нем интерфейсов (IValidate) и затем для вызова одного из членов этого интерфейса (Validate):

MyControl myControl = new MyControlO;


IValidate val = (IValidate)myControl; bool success = val.ValidateO;

Что будет, если клиент попытается использовать класс так, как если бы в последнем был реализован метод, на самом деле в нем не реализованный? Следующий пример будет скомпилирован, поскольку интерфейс ISerializable является допустимым. И все же в период выполнения будет передано исключение System.InvalidCastException, так как в MyGrid не реализован интерфейс ISerializable. После этого выполнение приложения прервется, если только исключение не будет явно уловлено.

using System;

public class FancyControl

{

protected string Data; public string data {

get {

return this.Data; }

set {

this.Data = value;

> } }

interface ISerializable {

bool Save(); }

interface IValidate {

bool ValidateO; }

class MyControl : FancyControl, IValidate {

public MyControlO

{

data = "my grid data";

>

public bool ValidateO {

Console.WriteLine("Validating...{0}", data);

return true; > }

class IsOperatorlApp {

public static void Main()

{

MyControl rayControl = new MyControlO;

ISerializable ser = (ISerializable)myControl;

// Заметьте: в результате этого будет сгенерировано // исключение System.InvalidateCastException, поскольку // в классе не реализован интерфейс ISerializable. bool success = ser.Save();

Console.WriteLine("The saving of '{0}' was {1}successful",

myControl.data,

(true == success ? "" : "not "));

} }

Конечно, улавливание исключения не повлияет на то, что предназначенный для выполнения код в этом случае не будет исполнен. Способ запроса объекта перед попыткой его приведения — вот что вам нужно. Один из способов — задействовать оператор is. Он позволяет в период выполнения проверять совместимость одного типа с другим. Оператор имеет следующий вид, где выражение — ссылочный тип:

выражение is тип

Результат оператора is — булево значение, которое затем можно использовать с условными операторами. В следующем примере я изменил код, чтобы проверять совместимость между классом MyControl и интерфейсом ISerializable перед попыткой вызова метода ISerializable:

using System;

public class FancyControl

{

protected string Data; public string data {

get

{

return this.Data;

}

set

{

this.Data = value;

} }

}

interface ISerializable {

bool Save(); >

interface IValidate {

bool ValidateO;

}

class MyControl : FancyControl, IValidate {

public MyControlO

{

data = "my grid data";

}

public bool ValidateQ {

Console.WriteLine("Validating...{0}", data);

return true; > }

class IsOperator2App {

public static void Main()

{

MyControl myControl = new MyControlO;

if (myControl is ISerializable) {

ISerializable ser = (ISerializable)myControl;

bool success = ser.SaveO;

Console. WriteLinef'The saving of '{0}' was "+ "{1}successful", myControl.data,

(true == success ? "" : "not ")); }

else {

Console.WriteLine("The ISerializable interface "+ "is not implemented."); > } }

Вы увидели, как оператор is позволяет проверить совместимость двух типов, чтобы гарантировать их корректное использование. А теперь рассмотрим его близкого родственника — оператор as и сравним их.

 

Содержание раздела