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:
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.
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:
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:
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:
If Document implements only the IStorable interface but not the ICompressible interface:
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:
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.
UNIT TESTING PART ONE
UNIT TESTING PART TWO
UNIT TESTING PART THREE
WINDOWS COMPLIANCE GUI TESTING PART ONE
WINDOWS COMPLIANCE GUI TESTING PART TWO
WINDOWS COMPLIANCE GUI TESTING PART THREE
WINDOWS COMPLIANCE GUI TESTING PART FOUR VALIDATION TESTING
WINDOWS COMPLIANCE GUI TESTING PART FIVE CONDITION TESTING
WINDOWS COMPLIANCE GUI TESTING PART SIX GENERAL CONDITION TESTING
TESTING CONDITIONS PART ONE
TESTING CONDITIONS PART TWO
TESTING CONDITIONS PART THREE
TESTING CONDITIONS PART FOUR
SPECIFIC FIELD TESTING
INTEGRATION TESTING PART ONE
INTEGRATION TESTING PART TWO
INTEGRATION TESTING PART THREE
INTEGRATION TESTING PART FOUR
INTEGRATION TESTING PART FIVE
INTEGRATION TEST STANDARDS
INTEGRATION TEST STANDARDS PART TWO