2.4. Properties

Often the internal representation of a class is modified after its initial release to users. For example, in this first version of WordCount, m_trace is declared as a bool data member; that is, it is able to be set either to true or to false. For large text files, however, users have found the generated trace text overwhelming—at least when generated to the console. They have requested that we allow them to specify whether to direct the trace to the console or to a file. Supporting this flexibility requires a change to the type representation of m_trace. It must now be able to represent three states: traceOff, toConsole, and toFile.

If m_trace is declared as public, users are free to access it directly within their code. The result is a tight coupling of the user's code with the class implementation—a tight coupling that the class designer is unaware of, at least until she changes the class implementation and the user discovers that his program is now broken.

Information hiding is the process of making the implementation details of a class inaccessible to users. This mechanism provides a loose coupling between the user's code and the class implementation, thereby enhancing the ability of the designer to modify the class implementation without disrupting the user's program. We enforce information hiding for class data members by declaring them as private.

Information hiding solves the problem of tight coupling. It also creates the problem of how to allow users read or write access to a private data member. In C#, the solution is to provide get and set accessors within a named class property—for example,

public class WordCount
{
      // private data member declaration
      private string m_file_output;

      // associated public property
      public string OutFile
      {
          get{ return m_file_output; }   // Read  access
          set
          { // Write access
                if ( value.Length != 0 )
                      m_file_output = value;
          }
      }

      // ...
}

A property typically is a public class member providing read and possibly write access to a private data member of the class. We define a property by specifying an access level, type, and property name. OutFile, for example, is a public property of type string.

If we wish the property to support read access, we provide a get accessor. It must return a value of the property's type. The associated code is placed within a statement block. It does not specify a return type or signature. At its simplest, a get accessor returns the data member it encapsulates.

If we wish the property to support write access, we provide a set accessor. Within the set accessor, the identifier value is always an object of the same type as its containing property. At runtime, value is bound to the right-hand side of the assignment. At its simplest, a set accessor assigns value to the data member it encapsulates.

The user accesses a property as if it were a data member rather than a function. For example, in the code fragment

string defaultFile = @"c:	extwordCount.txt";

if ( theObj.OutFile == null )
     theObj.OutFile = defaultFile;

the occurrence of OutFile within the condition of the if statement is replaced by the body of the get accessor. The second occurrence of OutFile that is the target of the assignment is replaced by the body of the set accessor. value is bound to the string object defaultFile.

If we wish to restrict a property to read-only access, we simply don't provide a set accessor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.22.23