Exposing and Restricting Access to Members


Exposing and Restricting Access to Members

The members of a class are private by default. When designing your class it's a good idea to leave as many things as possible private. This is called information hiding. When you mark something public, a developer using your class will have dependencies on those public members, and sometimes that prevents you from modifying your class the way it needs to be in future releases.

For example, in Figure 5.9 , suppose that we decided to make Balance public. A developer could set the Balance field directly outside the class. This may be okay in the first release but imagine if later we want to have some code trigger if the Balance is ever set to a negative number. By having exposed the Balance field we can no longer inject code that triggers automatically based on how that field changes. A better approach is to keep the Balance field private, and add public functions like MakeDeposit and MakeWithdrawal ( Figure 5.10 ). These two functions in turn set the value of the Balance field. The fact that the developer doesn't get direct access to the Balance field means that we can change the code that affects the field in later releases.

Figure 5.9 You should assume that if you mark a field as public, the programmer using the class will most likely use it and then have a dependency on that field in future versions of the class.
 class Account {  public  decimal balance; } class Bank {    static void CreateAccount()    {       Savings s = new Savings();       // direct access to balance  s.balance  += 1000m;    } } 
Figure 5.10 Rather than exposing a field like Balance, it is better to hide it by marking it private and then create public functions that enable the programmer using the class to access the field indirectly.
 class Account {  private  decimal balance;    //A better way to access balance    public void  MakeDeposit  (                decimal amount)    {       balance += amount;    }    public void  MakeWithdrawal  (                decimal amount)    {       if(balance >= amount)          balance -= amount;       else          throw new          InvalidOperationException          ("Not enough Money");    } } class Bank {    static void CreateAccount()    {       Savings s = new Savings();  // no direct access to balance  s.MakeDeposit(1000m);    } } 

To change the scope of a member:

  • Table 5.1 shows the different scope modifiers. Add one of these modifiers in front of the member declaration. Apply to fields, properties, functions, events, nested classes, etc.

graphics/tick.gif Tips

  • Classes also have a scope. The scope for classes is either internal (default) or public . A public class can be used by any other code. An internal class can be used by any code that lives in the same assembly. Assembly is an abstract boundary for types. It normally refers to a DLL or an EXE. In C# Web Applications all the code in the same project ends up in a single DLL. A class marked as internal can only be used by other code in the same DLL. If you wanted to use the DLL from one project in another project (you'll learn how to do this in various chapters of the book), you need to mark the class as public. For the most part it's best to keep classes as the default, internal, until there's a need to make them public ( Figure 5.11 ).

    Figure 5.11 By default, classes are internal. That means that only other classes within the same project (or assembly, to be more accurate) can access the class.
     // class is only visible within the // assembly  internal class  Checking : Account {    // Checking implementation } // if not specified, default // accessibility is internal  class  Savings : Account {    // Savings implementation } 
  • You should always keep as much as possible private. If you feel you should expose a field to developers, keep the field private, but add a property to access the field. Then make the property protected or public depending on how much access developers require ( Figure 5.12 ).

    Figure 5.12 Adding a public property is another way of hiding a data member. Notice that in this case m_balance is private.
     class Account {    // m_balance is accessed via balance    // property  private  decimal m_balance = 0.0m;    // this is the balance property    public decimal balance  {   get   {  // could put business logic here        return m_balance;  }   set   {  // could put validation logic        // here        m_balance = value;  }   }  } 

Table 5.1. Member Scope Modifiers (Modifiers that Enable You to Expose or Hide Class Members)

MODIFIER

EXPLANATION

private (default)

Member can only be used inside of the class.

protected

Member can be used inside of the class, and by code in a class that derives from the class. The derived class can live in a different project. For example, you can write a DLL (Class Library Project) and place the class there, then inherit from it in a class of a Web Application project. The inherited class would be able to access protected members.

internal

Member can be used by any code that lives in the same project (assembly). If the class lives in an ASP.NET Web Application then the members are accessible only to other classes in the same ASP.NET Web Application.

protected internal

It is the combination of protected and internal. Member can be seen used outside of the project (assembly) if the class inherits from this class, and the member can be seen used by any class in the same project.

public

Members can be used by any code.



C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net