Casting to an Interface in c sharp

You can access the members (i.e., methods and properties) of an interface through the object of any class that implements the interface.

When you cast you say to the compiler, "trust me, I know this object is really of this type." In this case you are saying "trust me, I know this document really implements IStorable, so you can treat it as an IStorable."

Casting is safe to do because the Document object implements IStorable and thus is safely treated as an IStorable object. You cast by placing the type you are casting to in parentheses. The following line declares a variable of type IStorable and assigns to that variable the Document object, cast to type IStorable:

IStorable isDoc = (IStorable) doc;

You can read this line as "cast doc to IStorable and assign the resulting IStorable object to the variable isDoc, which is declared to be of type IStorable." Note that the variable isDoc is now a reference to the same document, but that reference is of type IStorable and so has the methods and properties of IStorable.

You are now free to use this IStorable variable to access the IStorable methods and properties of the document.

isDoc.status = 0; isDoc.Read();

In these two lines of code you set the status property of the document to zero, and you call the Read() method of the document. You can do so because Status and Read() are members of the IStorable interface implemented by the document.

You cannot instantiate an interface directly; that is, you cannot write:

IStorable isDoc = new IStorable();

You can, however, create an instance of the implementing class and then create an instance of the interface by casting the implementing object to the interface type:

IStorable isDoc = (IStorable) doc;

isDoc is a reference to an IStorable object to which you've assigned the document cast to IStorable.

Thus far, you have cast the Document object (doc) to IStorable and assigned the result to the reference to an IStorable: isDoc. You knew this was safe to do because you defined the Document class to implement IStorable.

However, there may be instances in which you do not know in advance (at compile time) that an object supports a particular interface. For instance, given a collection of objects, you might not know whether each object in the collection implements IStorable, ICompressible, or both.

You can find out what interfaces are implemented by a particular object by casting blindly and then catching the exceptions that arise when you've tried to cast the object to an interface it hasn't implemented. The code to cast Document to ICompressible might be:

Document doc = new Document("Test Document"); ICompressible icDoc = (ICompressible) doc; icDoc.Compress();

If Document implements only the IStorable interface but not the ICompressible interface:

public class Document : IStorable

the cast to ICompressible would still compile because ICompressible is a valid interface. However, because of the illegal cast, an exception will be thrown when the program is run:

An exception of type System.InvalidCastException was thrown.

You could then catch the exception and take corrective action, but this approach is ugly and evil and you should not do things this way. This is like testing whether a gun is loaded by firing it; it's dangerous and it annoys the neighbors.

Rather than firing blindly, you would like to be able to ask the object if it implements an interface, in order to then invoke the appropriate methods. C# provides two operators to help you ask the object if it implements an interface: the is operator and the as operator. The distinction between them is subtle but important.

No comments:

Post a Comment