Friday, 7 December 2012

Upload Excel File And Display in GridView Control in Webpage





Upload Excel File And Display in GridView Control in Webpage

First Create web Page and File Upload control and gridview
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ExcelFile.aspx.cs" Inherits="ExcelFile" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
 
  <asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server"
           
Height="21px" Text="Upload"
          Width="92px" onclick="btnUpload_Click"/>
</div>
<div>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView></div>
  </form>
</body>
</html>

Now Apply code in .cs file

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.OleDb;
using System.IO;
public partial class ExcelFile : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
  }
  protected void btnUpload_Click(object sender, EventArgs e)
  {
      //string Path;
      string connectionString = "";
      if (FileUpload1.HasFile)
      {
          string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
          string fileExtension = Path.GetExtension(FileUpload1.PostedFile.FileName);
          string fileLocation = Server.MapPath("~/File/" + fileName);
          FileUpload1.SaveAs(fileLocation);
          //Check whether file extension is xls or xslx
          if (fileExtension == ".xls")
          {
              connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
          }
          else if (fileExtension == ".xlsx")
          {
              connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
          }
          //Create OleDB Connection and OleDb Command
          OleDbConnection con = new OleDbConnection(connectionString);
          OleDbCommand cmd = new OleDbCommand();
          cmd.CommandType = System.Data.CommandType.Text;
          cmd.Connection = con;
          OleDbDataAdapter dAdapter = new OleDbDataAdapter(cmd);
          DataTable dtExcelRecords = new DataTable();
          con.Open();
          DataTable dtExcelSheetName = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
          string getExcelSheetName = dtExcelSheetName.Rows[0]["Table_Name"].ToString();
          cmd.CommandText = "SELECT * FROM [" + getExcelSheetName + "]";
          dAdapter.SelectCommand = cmd;
          dAdapter.Fill(dtExcelRecords);
          con.Close();
          GridView1.DataSource = dtExcelRecords;
          GridView1.DataBind();
      }
  }
}

Sunday, 25 November 2012

Delegates and Events

Delegates and Events

Clicking a submit button, moving the mouse across a Form, pushing an Enter key, a character being received on an I/O port—each of these is an event that usually triggers a call to one or more special event handling routines within a program.
In the .NET world, events are bona fide class members—equal in status to properties and methods. Just about every class in the Framework Class Library has event members. A prime example is the Control class, which serves as a base class for all GUI components. Its events—including Click, DoubleClick, KeyUp, and GotFocus—are designed to recognize the most common actions that occur when a user interacts with a program. But an event is only one side of the coin. On the other side is a method that responds to, or handles, the event. Thus, if you look at the Control class methods, you'll find OnClick, OnDoubleClick, OnKeyUp, and the other methods that correspond to their events.
Figure 3-3 illustrates the fundamental relationship between events and event handlers that is described in this section. You'll often see this relationship referred to in terms of publisher/subscriber, where the object setting off the event is the publisher and the method handling it is the subscriber.
Figure 3-3. Event handling relationships


Delegates

Connecting an event to the handling method(s) is a delegate object. This object maintains a list of methods that it calls when an event occurs. Its role is similar to that of the callback functions that Windows API programmers are used to, but it represents a considerable improvement in safeguarding code.
In Microsoft Windows programming, a callback occurs when a function calls another function using a function pointer it receives. The calling function has no way of knowing whether the address actually refers to a valid function. As a result, program errors and crashes often occur due to bad memory references. The .NET delegate eliminates this problem. The C# compiler performs type checking to ensure that a delegate only calls methods that have a signature and return type matching that specified in the delegate declaration. As an example, consider this delegate declaration:
public delegate void MyString (string msg);

When the delegate is declared, the C# compiler creates a sealed class having the name of the delegate identifier (MyString). This class defines a constructor that accepts the name of a method—static or instance—as one of its parameters. It also contains methods that enable the delegate to maintain a list of target methods. This means that—unlike the callback approach—a single delegate can call multiple event handling methods.
A method must be registered with a delegate for it to be called by that delegate. Only methods that return no value and accept a single string parameter can be registered with this delegate; otherwise, a compilation error occurs. Listing 3-11 shows how to declare the MyString delegate and register multiple methods with it. When the delegate is called, it loops through its internal invocation list and calls all the registered methods in the order they were registered. The process of calling multiple methods is referred to as multicasting.
Listing 3-11. Multicasting Delegate
// file: delegate.cs

using System;

using System.Threading;

class DelegateSample

{

   public delegate void MyString(string s);

   public static void PrintLower(string s){

      Console.WriteLine(s.ToLower());

   }



   public static void PrintUpper(string s){

      Console.WriteLine(s.ToUpper());

   }



   public static void Main()

   {

      MyString myDel;

      // register method to be called by delegate

      myDel =  new MyString(PrintLower);

      // register second method

      myDel += new MyString(PrintUpper);

      // call delegate

      myDel("My Name is Violetta.");

      // Output: my name is violetta.

      //         MY NAME IS VIOLETTA.

   }

}

Note that the += operator is used to add a method to the invocation list. Conversely, a method can be removed using the -= operator:
myDel += new MyString(PrintUpper); // register for callback

myDel -= new MyString(PrintUpper); // remove method from list

In the preceding example, the delegate calls each method synchronously, which means that each succeeding method is called only after the preceding method has completed operation. There are two potential problems with this: a method could "hang up" and never return control, or a method could simply take a long time to process—blocking the entire application. To remedy this, .NET allows delegates to make asynchronous calls to methods. When this occurs, the called method runs on a separate thread than the calling method. The calling method can then determine when the invoked method has completed its task by polling it, or having it call back a method when it is completed. Asynchronous calls are discussed in Chapter 13, "Asynchronous Programming and Multithreading."

Delegate-Based Event Handling

In abstract terms, the .NET event model is based on the Observer Design Pattern. This pattern is defined as "a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically."[1] We can modify this definition to describe the .NET event handling model depicted in Figure 3-3: "when an event occurs, all the delegate's registered methods are notified and executed automatically." An understanding of how events and delegates work together is the key to handling events properly in .NET.
[1] Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides; Addison-Wesley, 1995.
To illustrate, let's look at two examples. We'll begin with built-in events that have a predefined delegate. Then, we'll examine how to create events and delegates for a custom class.
Working with Built-In Events
The example in Listing 3-12 displays a form and permits a user to draw a line on the form by pushing a mouse key down, dragging the mouse, and then raising the mouse key. To get the endpoints of the line, it is necessary to recognize the MouseDown and MouseUp events. When a MouseUp occurs, the line is drawn.
The delegate, MouseEventHandler, and the event, MouseDown, are predefined in the Framework Class Library. The developer's task is reduced to implementing the event handler code and registering it with the delegate. The += operator is used to register methods associated with an event.
this.MouseDown += new MouseEventHandler(OnMouseDown);

The underlying construct of this statement is
this.event += new delegate(event handler method);

To implement an event handler you must provide the signature defined by the delegate. You can find this in documentation that describes the declaration of the MouseEventHandler delegate:
public delegate void MouseEventHandler(

   object sender,

   MouseEventArgs e)

Listing 3-12. Event Handler Example
using System;

using System.Windows.Forms;

using System.Drawing;

class DrawingForm:Form

{

   private int lastX;

   private int lastY;

   private Pen myPen= Pens.Black; // defines color of drawn line

   public DrawingForm() {

      this.Text = "Drawing Pad";

      // Create delegates to call MouseUp and MouseDown

      this.MouseDown += new MouseEventHandler(OnMouseDown);

      this.MouseUp   += new MouseEventHandler(OnMouseUp);

   }

   private void OnMouseDown(object sender, MouseEventArgs e)

   {

      lastX = e.X;

      lastY = e.Y;

   }

   private void OnMouseUp(object sender, MouseEventArgs e)

   {

      // The next two statements draw a line on the form

      Graphics g = this.CreateGraphics();

      if (lastX >0 ){

         g.DrawLine(myPen, lastX,lastY,e.X,e.Y);

      }

      lastX = e.X;

      lastY = e.Y;

   }

   static void Main() {

      Application.Run(new DrawingForm());

   }

}

Using Anonymous Methods with Delegates
.NET 2.0 introduced a language construct known as anonymous methods that eliminates the need for a separate event handler method; instead, the event handling code is encapsulated within the delegate. For example, we can replace the following statement from Listing 3-12:
this.MouseDown += new MouseEventHandler(OnMouseDown);

with this code that creates a delegate and includes the code to be executed when the delegate is invoked:
this.MouseDown += delegate(object sender, EventArgs e)

{

   lastX = e.X;

   lastY = e.Y;

}

The code block, which replaces OnMouseDown, requires no method name and is thus referred to as an anonymous method. Let's look at its formal syntax:
delegate [(parameter-list)] {anonymous-method-block}

  • The delegate keyword is placed in front of the code that is executed when the delegate is invoked.
  • An optional parameter list may be used to pass data to the code block. These parameters should match those declared by the delegate. In this example, the parameters correspond to those required by the predefined delegate MouseEventHandler.
  • When the C# compiler encounters the anonymous code block, it creates a new class and constructs a method inside it to contain the code block. This method is called when the delegate is invoked.
To further clarify the use of anonymous methods, let's use them to simplify the example shown earlier in Listing 3-11. In the original version, a custom delegate is declared, and two callback methods are implemented and registered with the delegate. In the new version, the two callback methods are replaced with anonymous code blocks:
// delegate declaration

public delegate void MyString(string s);



// Register two anonymous methods with the delegate

MyString myDel;

myDel =  delegate(string s) { Console.WriteLine(s.ToLower()); };

myDel += delegate(string s) { Console.WriteLine(s.ToUpper()); };

// invoke delegate

myDel("My name is Violetta");

When the delegate is called, it executes the code provided in the two anonymous methods, which results in the input string being printed in all lower- and uppercase letters, respectively.
Defining Custom Events
When writing your own classes, it is often necessary to define custom events that signal when some change of state has occurred. For example, you may have a component running that monitors an I/O port and notifies another program about the status of data being received. You could use raw delegates to manage the event notification; but allowing direct access to a delegate means that any method can fire the event by simply invoking the delegate. A better approach—and that used by classes in the Framework Class Library—is to use the event keyword to specify a delegate that will be called when the event occurs.
The syntax for declaring an event is
public event  <delegate name>  <event name>

Let's look at a simple example that illustrates the interaction of an event and delegate:
public class IOMonitor

{

   // Declare delegate

   public delegate void IODelegate(String s);

   // Define event variable

   public event IODelegate DataReceived ;

   // Fire the event

   public void FireReceivedEvent (string msg)

   {

      if (DataReceived != null)  // Always check for null

      {

         DataReceived(msg);      // Invoke callbacks

      }

   }

}

This code declares the event DataReceived and uses it in the FireReceivedEvent method to fire the event. For demonstration purposes, FireReceivedEvent is assigned a public access modifier; in most cases, it would be private to ensure that the event could only be fired within the IOMonitor class. Note that it is good practice to always check the event delegate for null before publishing the event. Otherwise, an exception is thrown if the delegate's invocation list is empty (no client has subscribed to the event).
Only a few lines of code are required to register a method with the delegate and then invoke the event:
IOMonitor monitor = new IOMonitor();

// You must provide a method that handles the callback

monitor.DataReceived += new IODelegate(callback method);

monitor.FireReceivedEvent("Buffer Full");  // Fire event

Defining a Delegate to Work with Events
In the preceding example, the event delegate defines a method signature that takes a single string parameter. This helps simplify the example, but in practice, the signature should conform to that used by all built-in .NET delegates. The EventHandler delegate provides an example of the signature that should be used:
public delegate void EventHandler(object sender,

                                  EventArgs eventArgs);

The delegate signature should define a void return type, and have an object and EventArgs type parameter. The sender parameter identifies the publisher of the event; this enables a client to use a single method to handle and identify an event that may originate from multiple sources.
The second parameter contains the data associated with the event. .NET provides the EventArgs class as a generic container to hold a list of arguments. This offers several advantages, the most important being that it decouples the event handler method from the event publisher. For example, new arguments can be added later to the EventArgs container without affecting existing subscribers.
Creating an EventArgs type to be used as a parameter requires defining a new class that inherits from EventArgs. Here is an example that contains a single string property. The value of this property is set prior to firing the event in which it is included as a parameter.
public class IOEventArgs: EventArgs

{

   public IOEventArgs(string msg){

      this.eventMsg = msg;

   }

   public string Msg{

      get {return eventMsg;}

   }

   private string eventMsg;

}

IOEventArgs illustrates the guidelines to follow when defining an EventArgs class:
  • It must inherit from the EventArgs class.
  • Its name should end with EventArgs.
  • Define the arguments as readonly fields or properties.
  • Use a constructor to initialize the values.
If an event does not generate data, there is no need to create a class to serve as the EventArgs parameter. Instead, simply pass EventArgs.Empty.
Core Note

If your delegate uses the EventHandler signature, you can use EventHandler as your delegate instead of creating your own. Because it is part of the .NET Framework Class Library, there is no need to declare it.

An Event Handling Example
Let's bring these aforementioned ideas into play with an event-based stock trading example. For brevity, the code in Listing 3-13 includes only an event to indicate when shares of a stock are sold. A stock purchase event can be added using similar logic.
Listing 3-13. Implementing a Custom Event-Based Application
//File: stocktrader.cs

using System;

// (1) Declare delegate

public delegate void TraderDelegate(object sender,

                                    EventArgs e);

// (2) A class to define the arguments passed to the delegate

public class TraderEventArgs: EventArgs

{

   public TraderEventArgs(int shs, decimal prc, string msg,

                          string sym){

      this.tradeMsg   = msg;

      this.tradeprice = prc;

      this.tradeshs   = shs;

      this.tradesym   = sym;

   }

   public string Desc{

      get {return tradeMsg;}

   }

   public decimal SalesPrice{

      get {return tradeprice;}

   }

   public int Shares{

      get {return tradeshs;}

   }

   public string Symbol{

       get {return tradesym;}

   }



   private string  tradeMsg;

   private decimal tradeprice;

   private int tradeshs;

   private string tradesym;

}

// (3) class defining event handling methods

public class EventHandlerClass

{

   public void HandleStockSale(object sender,EventArgs e)

   {

      // do housekeeping for stock purchase

      TraderEventArgs ev = (TraderEventArgs) e;

      decimal totSale = (decimal)(ev.Shares * ev.SalesPrice);

      Console.WriteLine(ev.Desc);

   }

   public void LogTransaction(object sender,EventArgs e)

   {

      TraderEventArgs ev = (TraderEventArgs) e;

      Console.WriteLine(ev.Symbol+" "+ev.Shares.ToString()

                        +" "+ev.SalesPrice.ToString("###.##"));

   }

}

// (4) Class to sell stock and publish stock sold event

public class Seller

{

   // Define event indicating a stock sale

   public event TraderDelegate StockSold;

   public void StartUp(string sym, int shs, decimal curr)

   {

      decimal salePrice= GetSalePrice(curr);

      TraderEventArgs t = new TraderEventArgs(shs,salePrice,

            sym+" Sold at "+salePrice.ToString("###.##"), sym);

      FireSellEvent(t);  // Fire event

   }

   // method to return price at which stock is sold

   // this simulates a random price movement from current price

   private decimal GetSalePrice(decimal curr)

   {

      Random rNum = new Random();

      // returns random number between 0 and 1

      decimal rndSale = (decimal)rNum.NextDouble() * 4;

      decimal salePrice= curr - 2 + rndSale;

      return salePrice;

   }

   private void FireSellEvent(EventArgs e)

   {

      if (StockSold != null)  // Publish defensively

      {

         StockSold(this, e);  // Invoke callbacks by delegate

      }

   }

}



class MyApp

{

   public static void Main()

   {

      EventHandlerClass eClass= new EventHandlerClass();

      Seller sell = new Seller();

      // Register two event handlers for stocksold event

      sell.StockSold += new TraderDelegate(

                    eClass.HandleStockSale);

      sell.StockSold += new TraderDelegate(

                    eClass.LogTransaction);

      // Invoke method to sell stock(symbol, curr price,

                                     sell price)

      sell.StartUp("HPQ",100, 26);

   }

}

The class Seller is at the heart of the application. It performs the stock transaction and signals it by publishing a StockSold event. The client requesting the transaction registers two event handlers, HandleStockSale and LogTransaction, to be notified when the event occurs. Note also how the TRaderEvents class exposes the transaction details to the event handlers.

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.