Free mag vol1 | Page 866

CHAPTER 21  ADO.NET PART I: THE CONNECTED LAYER data reader’s overloaded indexer method. Here is a partial listing of the various GetXXX() methods defined by IDataRecord (see the .NET Framework 4.5 SDK documentation for a complete listing): public interface IDataRecord { int FieldCount { get; } object this[ string name ] { get; } object this[ int i ] { get; } bool GetBoolean(int i); byte GetByte(int i); char GetChar(int i); DateTime GetDateTime(int i); decimal GetDecimal(int i); float GetFloat(int i); short GetInt16(int i); int GetInt32(int i); long GetInt64(int i); ... bool IsDBNull(int i); }  Note You can use the IDataReader.IsDBNull() method to discover programmatically whether a specified field is set to null before obtaining a value from the data reader (to avoid triggering a runtime exception). Also recall that C# supports nullable data types (see Chapter 4), which are ideal for interacting with data columns that could be null in the database table. Abstracting Data Providers Using Interfaces At this point, you should have a better idea of the common functionality found among all .NET data providers. Recall that even though the exact names of the implementing types will differ among data providers, you can program against these types in a similar manner—that’s the beauty of interfacebased polymorphism. For example, if you define a method that takes an IDbConnection parameter, you can pass in any ADO.NET connection object, like so: public static void OpenConnection(IDbConnection cn) { // Open the incoming connection for the caller. cn.Open(); }  Note Interfaces are not strictly required; you can achieve the same level of abstraction using abstract base classes (such as DbConnection) as parameters or return values. 812