Friday, 23 November 2012

Methods

Methods

Methods are to classes as verbs are to sentences. They perform the actions that define the behavior of the class. A method is identified by its signature, which consists of the method name and the number and data type of each parameter. A signature is considered unique as long as no other method has the same name and matching parameter list. In addition to parameters, a method has a return type—void if nothing is returned—and a modifier list that determines its accessibility and polymorphic behavior.
For those who haven't recently boned up on Greek or object-oriented principles, polymorphism comes from the Greek poly (many) and morphos (shape). In programming terms, it refers to classes that share the same methods but implement them differently. Consider the ToString method implemented by all types. When used with an int type, it displays a numeric value as text; yet on a class instance, it displays the name of the underlying class—although this default should be overridden by a more meaningful implementation.
One of the challenges in using .NET methods is to understand the role that method modifiers play in defining the polymorphic behavior of an application. A base class uses them to signal that a method may be overridden or that an inheriting class must implement it. The inheriting class, in turn, uses modifiers to indicate whether it is overriding or hiding an inherited method. Let's look at how all this fits together.

Method Modifiers

In addition to the access modifiers, methods have seven additional modifiers shown in Table 3-4. Five of these—new, virtual, override, sealed, and abstract—provide a means for supporting polymorphism.
Table 3-4. Method Modifiers
Modifier
Description
static
The method is part of the class's state rather than any instances of the class. This means that it can be referenced directly by specifying classname.method (parameters) without creating an instance of the class.
virtual
Designates that the method can be overridden in a subclass. This cannot be used with static or private access modifiers.
override
Specifies that the method overrides a method of the same name in a base class. This enables the method to define behavior unique to the subclass. The overriden method in the base class must be virtual.
new
Permits a method in an inherited class to "hide" a non-virtual method with a same name in the base class. It replaces the original method rather than overriding it.
sealed
Prevents a derived class from overriding this method.
  • Is used in a derived class that will serve as the base for its own subclasses.
  • Must be used with the override modifier.
abstract
The method contains no implementation details and must be implemented by any subclass. Can only be used as a member of an abstract class.
extern
Indicates that the method is implemented externally. It is generally used with the DLLImport attribute that specifies a DLL to provide the implementation.


Static Modifier
As with other class members, the static modifier defines a member whose behavior is global to the class and not specific to an instance of a class. The modifier is most commonly used with constructors (described in the next section) and methods in helper classes that can be used without instantiation.
Listing 3-5. Static Method
using System;

class Conversions

{

   // class contains functions to provide metric conversions

   private static double cmPerInch = 2.54;

   private static double gmPerPound = 455;

   public static double inchesToMetric(double inches) {

      return(inches * cmPerInch);

   }

   public static double poundsToGrams(double pounds) {

      return(pounds * gmPerPound);

   }

}

class Test

{

   static void Main() {

      double cm, grams;

      cm = Conversions.inchesToMetric(28.5);

      grams = Conversions.poundsToGrams(984.4);

   }

}

In this example, the Conversions class contains methods that convert units from the English to metric system. There is no real reason to create an instance of the class, because the methods are invariant (the formulas never change) and can be conveniently accessed using the syntax classname.method(parameter).
Method Inheritance with Virtual and Override Modifiers
Inheritance enables a program to create a new class that takes the form and functionality of an existing (base) class. The new class then adds code to distinguish its behavior from that of its base class. The capability of the subclass and base class to respond differently to the same message is classical polymorphism. In practical terms, this most often means that a base and derived class(es) provide different code for methods having the same signature.
By default, methods in the base class cannot be changed in the derived class. To overcome this, .NET provides the virtual modifier as a cue to the compiler that a method can be redefined in any class that inherits it. Similarly, the compiler requires that any derived class that alters a virtual method preface the method with the override modifier. Figure 3-2 and Listing 3-6 provide a simple illustration of this.
Listing 3-6. Virtual Methods
using System;

class Fiber

{

   public  virtual string ShowMe() { return("Base");}

}

class Natural:Fiber

{

   public override string ShowMe() { return("Natural");}

}

class Cotton:Natural

{

   public override string ShowMe() { return("Cotton");}

}

class Test

{

   static void Main ()

   {

      Fiber fib1 = new Natural();  // Instance of Natural

      Fiber fib2 = new Cotton();   // Instance of Cotton

      string fibVal;

      fibVal = fib1.ShowMe();      // Returns "Natural"

      fibVal = fib2.ShowMe();      // Returns "Cotton"

   }

}

Figure 3-2. Relationship between base class and subclasses for Listing 3-6

In this example, Cotton is a subclass of Natural, which is itself a subclass of Fiber. Each subclass implements its own overriding code for the virtual method ShowMe.
fib1.ShowMe();    //returns  "Natural"

fib2.ShowMe();    //returns  "Cotton"

A subclass can inherit a virtual method without overriding it. If the Cotton class does not override ShowMe(), it uses the method defined in its base class Natural. In that case, the call to fib2.ShowMe() would return "Natural".
New Modifier and Versioning
There are situations where it is useful to hide inherited members of a base class. For example, your class may contain a method with the same signature as one in its base class. To notify the compiler that your subclass is creating its own version of the method, it should use the new modifier in the declaration.
ShowMe() is no longer virtual and cannot be overridden. For Natural to create its own version, it must use the new modifier in the method declaration to hide the inherited version. Observe the following:
  • An instance of the Natural class that calls ShowMe()invokes the new method:
    Natural myFiber = new Natural();
    
    string fibTtype = myFiber.ShowMe();  // returns "Natural"
    

  • Cotton inherits the new method from Natural:
    Cotton myFiber = new Cotton();
    
    string fibType = myFiber.ShowMe();   // returns "Natural"
    

  • If ShowMe were declared as private rather than public in Natural, Cotton would inherit ShowMe from Fiber, because it cannot inherit a method that is out of scope.
Listing 3-7. Using the New Modifier for Versioning
public class Fiber

{

   public string ShowMe()        {return("Base");}

   public virtual string GetID() {return("BaseID");}

}

public class Natural:Fiber

{

   // Hide Inherited version of ShowMe

   new public string ShowMe()     {return("Natural");}

   public override string GetID() {return("NaturalID");}

   }

public class Cotton:Natural

{  // Inherits two methods: ShowMe() and GetID()

}

Sealed and Abstract Modifiers
A sealed modifier indicates that a method cannot be overridden in an inheriting class; an abstract modifier requires that the inheriting class implement it. In the latter case, the base class provides the method declaration but no implementation.
This code sample illustrates how an inheriting class uses the sealed modifier to prevent a method from being overridden further down the inheritance chain. Note that sealed is always paired with the override modifier.
class A {

   public virtual void PrintID{....}

}

class B: A {

   sealed override public void PrintID{...}

}

class C:B {

   // This is illegal because it is sealed in B.

   override public void PrintID{...}

}

An abstract method represents a function with a signature—but no implementation code—that must be defined by any non-abstract class inheriting it. This differs from a virtual method, which has implementation code, but may be redefined by an inheriting class. The following rules govern the use abstract methods:
  • Abstract methods can only be declared in abstract classes; however, abstract classes may have non-abstract methods.
  • The method body consists of a semicolon:
    public abstract void myMethod();
    

  • Although implicitly virtual, abstract methods cannot have the virtual modifier.
  • A virtual method can be overridden by an abstract method.
When facing the decision of whether to create an abstract class, a developer should also consider using an interface. The two are similar in that both create a blueprint for methods and properties without providing the implementation details. There are differences between the two, and a developer needs to be aware of these in order to make the better choice. The section on interfaces in this chapter offers a critical comparison.

Passing Parameters

By default, method parameters are passed by value, which means that a copy of the parameter's data—rather than the actual data—is passed to the method. Consequently, any change the target method makes to these copies does not affect the original parameters in the calling routine. If the parameter is a reference type, such as an instance of a class, a reference to the object is passed. This enables a called method to change or set a parameter value.
C# provides two modifiers that signify a parameter is being passed by reference: out and ref. Both of these keywords cause the address of the parameter to be passed to the target method. The one you use depends on whether the parameter is initialized by the calling or called method. Use ref when the calling method initializes the parameter value, and out when the called method assigns the initial value. By requiring these keywords, C# improves code readability by forcing the programmer to explicitly identify whether the called method is to modify or initialize the parameter.
The code in Listing 3-8 demonstrates the use of these modifiers.
Listing 3-8. Using the ref and out Parameter Modifiers
class TestParms

{

   public static void FillArray(out double[] prices)

   {

      prices = new double[4] {50.00,80.00,120.00,200.00};

   }

   public static void UpdateArray(ref double[] prices)

   {

      prices[0] = prices[0] * 1.50;

      prices[1] = prices[1] * 2.0;

   }

   public static double TaxVal(double ourPrice,

                               out double taxAmt)

   {

      double totVal = 1.10 * ourPrice;

      taxAmt = totVal – ourPrice;

      ourPrice = 0.0;  // Does not affect calling parameter

      return totVal;

   }

}

class MyApp

{

   public static void Main()

   {

      double[] priceArray;

      double taxAmt;

      //   (1) Call method to initialize array

      TestParms.FillArray(out priceArray);

      Console.WriteLine( priceArray[1].ToString());  // 80

      //   (2) Call method to update array

      TestParms.UpdateArray(ref priceArray);

      Console.WriteLine( priceArray[1].ToString());  // 160

      //   (3) Call method to calculate amount of tax.

      double ourPrice = 150.00;

      double newtax = TestParms.TaxVal(ourPrice, out taxAmt);

      Console.WriteLine( taxAmt.ToString());  // 15

      Console.WriteLine( ourPrice);           // 150.00

   }

}

In this example, the class MyApp is used to invoke three methods in the TestParms class:
  1. FillArray is invoked to initialize the array. This requires passing the array as a parameter with the out modifier.
  2. The returned array is now passed to a second method that modifies two elements in the array. The ref modifier indicates the array can be modified.
  3. ourPrice is passed to a method that calculates the amount of tax and assigns it to the parameter taxAmt. Although ourPrice is set to 0 within the method, its value remains unchanged in the calling method because it is passed by value.
C# includes one other parameter modifier, params, which is used to pass a variable number of arguments to a method. Basically, the compiler maps the variable number of arguments in the method invocation into a single parameter in the target method. To illustrate, let's consider a method that calculates the average for a list of numbers passed to it:
// Calculate average of variable number of arguments

public static double GetAvg(params double[] list)

{

   double tot = 0.0;

   for (int i = 0 ; i < list.Length; i++)

      tot += list[i];

   return tot / list.Length;

}

Except for the params modifier, the code for this method is no different than that used to receive an array. Rather than sending an array, however, the invoking code passes an actual list of arguments:
double avg;

avg = TestParms.GetAvg(12,15, 22, 5, 7 ,19);

avg = TestParms.GetAvg(100.50, 200, 300, 55,88,99,45);

When the compiler sees these method calls, it emits code that creates an array, populates it with the arguments, and passes it to the method. The params modifier is essentially a syntactical shortcut to avoid the explicit process of setting up and passing an array.

Tuesday, 20 November 2012

Generics

Generics

To understand and appreciate the concept of generics, consider the need to create a class that will manage a collection of objects. The objects may be of any type and are specified at compile time by a parameter passed to the class. Moreover, the collection class must be type-safe—meaning that it will accept only objects of the specified type.
In the 1.x versions of .NET, there is no way to create such a class. Your best option is to create a class that contains an array (or other container type) that treats everything as an object. As shown here, casting, or an as operator, is then required to access the actual object type. It is also necessary to include code that verifies the stored object is the correct type.
Object[] myStack = new object[50];

myStack[0] = new Circle(5.0);    // place Circle object in array

myStack[1] = "Circle";           // place string in array

Circle c1 = myStack[0] as Circle;

if( c1!=null) {                  // circle object obtained

Circle c2 = (Circle) myStack[1]; // invalid case exception

Generics, introduced with .NET 2.0, offer an elegant solution that eliminates the casting, explicit type checking, and boxing that occurs for value type objects. The primary challenge of working with generics is getting used to the syntax, which can be used with a class, interface, or structure.
The best way to approach the syntax is to think of it as a way to pass the data type you'll be working with as a parameter to the generic class. Here is the declaration for a generic class:
public class myCollection<T>

{

   T[] myStack = new T[50];

}

The type parameter T is placed in brackets and serves as a placeholder for the actual type. The compiler recognizes any reference to T within the body of the class and replaces it with the actual type requested. As this statement shows, creating an instance of a generic class is straightforward:
myCollection <string> = new myCollection<string>;

In this case, string is a type argument and specifies that the class is to work with string types only. Note that more than one type parameter may be used, and that the type parameter can be any name, although Microsoft uses (and recommends) single characters in its generic classes.
Although a class may be generic, it can restrict the types that it will accept. This is done by including an optional list of constraints for each type parameter. To declare a constraint, add the where keyword followed by a list of parameter/requirement pairs. The following declaration requires that the type parameter implement the ISerializable and IComparable interfaces:
public class myCollection<T> where

   T:ISerializable,

   T:IComparable

A parameter may have multiple interface constraints and a single class restraint. In addition, there are three special constraints to be aware of:
class— Parameter must be reference type.
struct— Parameter must be value type.
new()— Type parameter must have a parameterless constructor.
An example of a generic class is provided in Listing 3-16. The class implements an array that manages objects of the type specified in the type parameter. It includes methods to add items to the array, compare items, and return an item count. It includes one constraint that restricts the type parameter to a reference type.
Listing 3-16. A Generic Class to Hold Data
using System.Collections.Generic

public class GenStack<T>

   where T:class    // constraint restricts access to ref types

{

   private T[] stackCollection;

   private int count = 0;

   // Constructor

   public GenStack(int size)

   {

      stackCollection = new T[size];

   }

   public void Add(T item)

   {

      stackCollection[count] = item;

      count += 1;

   }

   // Indexer to expose elements in internal array

   public T this[int ndx]

   {

      get

      {

         if (!(ndx < 0 || ndx > count - 1))

            return stackCollection[ndx];

         // Return empty object

         else return (default(T));

      }

   }

   public int ItemCount

   {

      get {return count;}

   }

   public int Compare<C>(T value1, T value2)

   {

      // Case-sensitive comparison: -1, 0(match), 1

      return Comparer<T>.Default.Compare(value1, value2);

   }

}

The following code demonstrates how a client could access the generic class described in Listing 3-16:
// Create instance to hold 10 items of type string

GenStack<string> myStack = new GenStack<string>(10);

myStack.Add("Leslie");

myStack.Add("Joanna");

Console.WriteLine(myStack.ItemCount);  // 2

Console.WriteLine(myStack[1]);         // Joanna

int rel = myStack.Compare<string>("Joanna", "joanna");  // -1

Console.WriteLine(rel.ToString());

Class in C#

Introduction to a C# Class

Figure 3-1 displays a class declaration followed by a body containing typical class members: a constant, fields, a constructor containing initialization code, a property, and a method. Its purpose is to familiarize you with the syntax common to most C# classes and serve as a reference for later examples.

Defining a Class
A class definition consists of an optional attributes list, optional modifiers, the word class followed by the class identifier (name), and an optional list containing a base class or interfaces to be used for inheritance. Following this class declaration is the class body, consisting of the code and class members such as methods and properties.
Syntax for class definition:

[attributes] [modifiers] class  identifier [:baselist]

{class body} [;]


Classes—as do all .NET types—inherit from the System.Object class. This inheritance is implicit and is thus not specified as part of the class definition. As we'll see in the discussion of inheritance, this is important because a class can explicitly inherit from only one class.
Attributes
The optional attribute section consists of a pair of square brackets surrounding a comma-separated list of one or more attributes. An attribute consists of the attribute name followed by an optional list of positional or named arguments. The attribute may also contain an attribute target—that is, the entity to which the attribute applies.
Examples
The attribute section contains an attribute name only:

[ClassDesc]


Single attribute with named argument and positional argument (0):

[ClassDesc(Author="Knuth", 0)]


Multiple attributes can be defined within brackets.:

[ClassDesc(Author="Knuth"), ClassDesc(Author="James")]


Description
Attributes provide a way to associate additional information with a target entity. In our discussion, the target is a newly created class; but attributes may also be associated with methods, fields, properties, parameters, structures, assemblies, and modules. Their simple definition belies a truly innovative and powerful programming tool. Consider the following:
  • An attribute is an instance of a public class. As such, it has fields and properties that can be used to provide rich descriptive information about a target or targets.
  • All compilers that target the Common Language Runtime (CLR) recognize attributes and store information about them in the module's metadata. This is an elegant way to attach information to a program entity that can affect its behavior without modifying its implementation code. An application can then use reflection (a set of types for reading metadata) to read the metadata at runtime and make decisions based on its value.
  • Hundreds of predefined attributes are included in the .NET Framework Class Library (FCL). They are used heavily in dealing with interoperability issues such as accessing the Win32API or allowing .NET applications and COM objects to communicate. They also are used to control compiler operations. The[assembly:CLSComplianttrue)] attribute in Figure 3-1 tells the C# compiler to check the code for CLS compliance.
Core Note
Attributes provide a way to extend the metadata generated by the C# compiler with custom descriptive information about a class or class member.

.NET supports two types of attributes: custom attributes and standard attributes. Custom attributes are defined by the programmer. The compiler adds them to the metadata, but it's up to the programmer to write the reflection code that incorporates this metadata into the program. Standard attributes are part of the .NET Framework and recognized by the runtime and .NET compilers. The Flags attribute that was discussed in conjunction with enums in Chapter 2, "C# Language Fundamentals," is an example of this; another is the conditional attribute, described next.
Conditional Attribute
The conditional attribute is attached to methods only. Its purpose is to indicate whether the compiler should generate Intermediate Language (IL) code to call the method. The compiler makes this determination by evaluating the symbol that is part of the attribute. If the symbol is defined (using the define preprocessor directive), code that contains calls to the method is included in the IL. Here is an example to demonstrate this:
File: attribs.cs (attribs.dll)

#define DEBUG

using System;

using System.Diagnostics;   // Required for conditional attrib.

public class AttributeTest

{

   [Conditional("TRACE")]

   public static void ListTrace()

   { Console.WriteLine("Trace is On"); }

   [Conditional("DEBUG")]

   public static void ListDebug()

   { Console.WriteLine("Debug is On"); }

}


File: attribclient.cs (attribclient.exe)

#define TRACE

using System;

public class MyApp {

   static void Main()

   {

      Console.WriteLine("Testing Method Calls");

      AttributeTest.ListTrace();

      AttributeTest.ListDebug();

   }

}


Executing attribclient yields the following output:

Testing Method Calls

Trace is On


When attribclient is compiled, the compiler detects the existence of the trACE symbol, so the call to ListTrace is included. Because DEBUG is not defined, the call to ListDebug is excluded. The compiler ignores the fact that DEBUG is defined in attribs; its action is based on the symbols defined in the file containing the method calls. Note that a conditional attribute can be used only with methods having a return type of void.
Access Modifiers
The primary role of modifiers is to designate the accessibility (also called scope or visibility) of types and type members. Specifically, a class access modifier indicates whether a class is accessible from other assemblies, the same assembly, a containing class, or classes derived from a containing class.
public
A class can be accessed from any assembly.
protected
Applies only to a nested class (class defined within another class). Access is limited to the container class or classes derived from the container class.
internal
Access is limited to classes in the same assembly. This is the default access.
private
Applies only to a nested class. Access is limited to the container class.
protected internal
The only case where multiple modifiers may be used.
internal
Access is limited to the current assembly or types derived from the containing class.

Core Note
A base class must be at least as accessible as its derived class. The following raises an error:

class  Furniture { }               // default access is internal

public class Sofa : Furniture { }  // error


The error occurs because the Furniture class (internal by default) is less accessible than the derived Sofa class. Errors such as this occur most frequently when a developer relies on a default modifer. This is one reason that modifiers should be included in a declaration.

Abstract, Sealed, and Static Modifiers
In addition to the access modifiers, C# provides a dozen or so other modifiers for use with types and type members. Of these, three can be used with classes: abstract, sealed, and static.
abstract
Indicates that a class is to be used only as a base class for other classes. This means that you cannot create an instance of the class directly. Any class derived from it must implement all of its abstract methods and accessors. Despite its name, an abstract class can possess nonabstract methods and properties.
sealed
Specifies that a class cannot be inherited (used as a base class). Note that .NET does not permit a class to be both abstract and sealed.
static
Specifies that a class contains only static members (.NET 2.0).

Class Identifier
This is the name assigned to the class. The ECMA standard recommends the following guidelines for naming the identifier:
  • Use a noun or noun phrase.
  • Use the Pascal case capitalization style: The first letter in the name and the first letter of each subsequent concatenated word are capitalized—for example, BinaryTree.
  • Use abbreviations sparingly.
  • Do not use a type prefix, such as C, to designate all classes—for example, BinaryTree, not CBinaryTree.
  • Do not use the underscore character.
  • By convention, interface names always begin with I; therefore, do not use I as the first character of a class name unless I is the first letter in an entire word—for example, IntegralCalculator.
Base Classes, Interfaces, and Inheritance
This optional list contains a previously defined class or interface(s) from which a class may derive its behavior and capabilities. The new class is referred to as the derived class, and the class or interface from which it inherits is the base class or interface. A base class must be listed before any interface(s).
Example

// .. FCL Interface and user-defined base class

public interface System.Icomparable

   {Int32 CompareTo(Object object); }

class Furniture {  }

// .. Derived Classes

class Sofa: Furniture { ... }  // Inherits from one base class

// Following inherits from one base class and one interface.

class Recliner: Furniture, IComparable {...}


The C# language does not permit multiple class inheritance, thus the base list can contain only one class. Because there is no limit on the number of inherited interfaces, this serves to increase the role of interfaces in the .NET world.
 

Overview of Class Members

Table 3-1 provides a summary of the types that comprise a .NET class. They can be classified broadly as members that hold data—constants, fields, and properties—and members that provide functionality—the constructor, method, and event. We'll look at each individually.
Table 3-1. Class Members
Member Type
Valid In
Description
Constant
Class, Structure
A symbol that represents an unchanging value. The compiler associates it with the class—not an instance of the class.
Field
Class, Structure
A variable that holds a data value. It may be read-only or read/write.
Property
Class, Structure
Provides access to a value in a class. It uses an accessor that specifies the code to be executed in order to read or write the value. The code to read or write to a property is implemented implicitly by .NET as two separate methods.
Constructor
Class, Structure
C# has three types of constructors:
Instance. Initializes fields when an instance of a class is created.
Private. Commonly used to prevent instances of a class from being created.
Static. Initializes class before any instance is created.
Method
Class, Structure, Interface
A function associated with the class that defines an action or computation.
Events
Class, Structure, Interface
A way for a class or object to notify other classes or objects that its state has changed.
Types
Class, Structure, Interface
Classes, interfaces, structs, delegates.


Member Access Modifiers

The access modifiers used for a class declaration can also be applied to class members. They determine the classes and assemblies that have access to the class. Table 3-2 summarizes the scope of accessibility.
Table 3-2. Summary of Accessibility Provided by Access Modifiers
 
Access Modifiers
Class can be accessed by classes in:
Public
protected
Internal
private
Another assembly
Yes
No
Same assembly
Yes
Yes
Containing class
Yes
Yes
Yes
Yes
Class derived from containing class
Yes
Yes
Yes
No