top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Creating Collection Classes In C#

0 votes
156 views

Introduction

Collection classes are used frequently in .NET. For example, classes like ArrayList, NamevalueCollection, HashTable are collection classes. One peculiar thing of collection classes is that they can be used in foreach(...) loop in C#. VB.NET has similar construct For...Each. Your custom classes can also be iterated in this way if you implement certain interfaces. In this article we will see how to code collection classes using C#.

Sample Class

For our example we will assume that we need some data structure in which we will store list of book titles. We should be able to add, remove and iterate through the set of book titles. We will create a collection class called Books that will store these titles. Before going in to the details of creating collection class let us see the Books class in its most basic form.

namespace CollectionClass
{
class Books
{
	private ArrayList m_booktitles;
	public Books()
	{
		m_booktitles=new ArrayList();
	}

	public void Add(string booktitle)
	{
		m_booktitles.Add(booktitle);
	}

	public void Remove(string booktitle)
	{
		m_booktitles.Remove(booktitle);
	}
}
}

You will notice that we have provided easy way to add and remove items to the books class via ArrayList. However, we can not iterate the class using foreach construct. In order to achieve this we have to :

  • Implement System.Collections.IEnumerable interface in Books class
  • Create a class that implements System.Collections.IEnumerator interface

IEnumerable Interface

IEnumerable interface has only one method GetEnumerator() that returns a class that implements IEnumerator interface. Following code shows Books class after implementing IEnumerable interface.

class Books:IEnumerable
{
	public ArrayList m_booktitles;

	public Books()
	{
		m_booktitles=new ArrayList();
	}

	public void Add(string booktitle)
	{
		m_booktitles.Add(booktitle);
	}

	public void Remove(string booktitle)
	{
		m_booktitles.Remove(booktitle);
	}

	public IEnumerator GetEnumerator()
	{
		return new BooksEnumerator(this);
	}
}

The GetEnumerator() method returns an instance of class BooksEnumerator that we will discussed next.

IEnumerator Interface

IEnumerator interface resides in System.Collection namespace. This interface has following method and property definitions that we need to implement:

public bool MoveNext()
{
}
public void Reset()
{
}
public object Current
{
}

This MoveNext tells us what to do when user wants to scroll forward in our collection. Reset sets the initial position of the collection i.e. -1. Current retrieves current item from the collection.

BooksEnumerator Class

Here is complete code of a class that implements IEnumerator interface.

class BooksEnumerator : IEnumerator
{
	private int position = -1;
	private Books books;

	public BooksEnumerator(Books books)
	{
		this.books = books;
	}

	public bool MoveNext()
	{
		if (position < books.m_booktitles.Count - 1)
		{
			position++;
			return true;
		}
		else
		{
			return false;
		}
	}

	public void Reset()
	{
		position = -1;
	}

	public object Current
	{
		get
		{
			return books.m_booktitles[position];
		}
	}
}

We passed our Books class to the constructor of this class. This class then maintains a pointer to the current position in the collection.

Using Your Collection Class

You can now use your Books collection class in your code as follows:

class Class1
{
static void Main(string[] args)
{
	Books b=new Books();

	b.Add("vb.net");
	b.Add("c#");
	b.Add("asp.net");

	foreach(string s in b)
	{
		Console.WriteLine(s);
	}
}
}

Keep coding!

posted Dec 27, 2016 by Shivaranjini

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Introduction

This is about creating controls dynamically using C# in web pages. So I have considered Textboxes and labels to develop this.

Important Tasks

  1. Creating the text boxes when button is clicked.
  2. Creating text boxes as numbers are predefined.

Example

 

Discussed 2 examples. One I crated textboxes when the button is created. Here we can create any number of textboxes. In the second example we created textboxes inside a table when the row and columns are specified.

 

Demonstration

Creating the textboxes when button is clicked each time

 

image



Creating text boxes as numbers are predefined.

 

image

 

Implementation

Creating the textboxes when button is clicked each time

Here I have created the text boxes using C# in the code behind. The controls are created in each button click.

Code Snippet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


public partial class MultipleTextBox : System.Web.UI.Page
{

    protected void Page_load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //Remove the session when first time page loads.
            Session.Remove("clicks");
        }


    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        int rowCount = 0;

        //initialize a session.
        rowCount = Convert.ToInt32(Session["clicks"]);

        rowCount++;

        //In each button clic save the numbers into the session.
        Session["clicks"] = rowCount;


        //Create the textboxes and labels each time the button is clicked.
        for (int i = 0; i < rowCount; i++)
        {

            TextBox TxtBoxU = new TextBox();
        
            TextBox TxtBoxE = new TextBox();

            Label lblU = new Label();
            Label lblE = new Label();

            TxtBoxU.ID = "TextBoxU" + i.ToString();
            TxtBoxE.ID = "TextBoxE" + i.ToString();

            lblU.ID = "LabelU" + i.ToString();
            lblE.ID = "LabelE" + i.ToString();


            lblU.Text = "User " + (i + 1).ToString() + " : ";
            lblE.Text = "E-Mail : ";

            //Add the labels and textboxes to the Panel.
            Panel1.Controls.Add(lblU);
            Panel1.Controls.Add(TxtBoxU);

            Panel1.Controls.Add(lblE);
            Panel1.Controls.Add(TxtBoxE);
        

        }


    }

}



Creating text boxes as numbers are predefined.

Here I have created a table using C# and other controls as well.

Code Snippet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class AddDefinedTextBox : System.Web.UI.Page
{

    protected void Button1_Click1(object sender, EventArgs e)
    {


        int rowCount = Convert.ToInt32(TextBox1.Text);

        int columnCount = Convert.ToInt32(TextBox2.Text);

        Table table = new Table();

        table.ID = "table1";


        for (int i = 0; i < rowCount; i++)
        {

            TableRow row = new TableRow();

            for (int j = 0; j < columnCount; j++)
            {

                TableCell cell = new TableCell();

                TextBox TxtBoxU = new TextBox();


                TxtBoxU.ID = "TextBoxU" + i.ToString();

                cell.ID = "cell" + i.ToString();

                cell.Controls.Add(TxtBoxU);

                row.Cells.Add(cell);


            }


            table.Rows.Add(row);

        }


        Panel1.Controls.Add(table);

    }
}

READ MORE

Introduction

Microsoft introduced long running background application called Services along with Windows NT Operating System. These services are multithreaded. Writing a windows NT Service using VB 6 was a tedious job. However, VB.NET masks the task much easy. In this article I will show you how to create a simple Windows Service using VB.NET

Overview of Services

Windows service is a background process that performs certain task. You can start, stop, pause or resume services on remote and local computers. Windows also provide option to enable or disable a service. Objective of Windows service is to run application in the background in certain period even though machine is busy with other process or work. You can also set a user account that a service will use to log on.

Is Windows NT Service having an advantage over application running under Windows Scheduler?

As mentioned earlier, windows services are used to do certain task on regular intervals. Is this can be achieved by other way? Actually Yes. You can create an application for performing your task. Using windows scheduler you can call this application at regular intervals. What is the advantage of implementing Windows Service then? Normally windows services will not have a user interface. Windows services runs efficiently because of its own process. To start windows Scheduler, one of the user has to log on to system. Whereas Windows service can automatically started when system boots.

Creating a simple windows service

Before we start developing windows service one thing you have to remember. You can deploy the service only on OS that has NT based architecture. If you are working in Visual Studio .Net, you can see a windows service template on new project dialog. You have to code very less to test this simple windows service if you are using VS.NET. In this article we are going to create a simple windows service which will monitor a specific folder on the disk. If any file is renamed, created, modified or deleted, service will keep its track in the system log.

Open your VS.NET and select windows service project and enter the name folderSPY and click ok. Double click the design form or Press Shift + F7. On the top section of code window, enter the following:

Imports System.IO
Public folderToWatch as fileSystemWatcher

On the OnStart procedure type the following

Dim strSysDir As String
folderToWatch = new fileSystemWatcher()

To watch system directory

strSysDir = System.Enviroment.SystemDirectory()

Set the path of the folder which you want to watch. Here our service is watching WINNT folder.

folderToWatch.path = strSysDir

To monitor above mentioned folder, you have to set certain filters.

With folderToWatch
	.notifyFilter = .notifyFilter 
				OR notifyFilters.FileName
	.notifyFilter = .notifyFilter 
				OR notifyFilters.Attributes
	'To watch sub directories....
	 .includeSubDirectories = True
End With

How to know whether any user changed the file name or file attributes?

To know this you need handlers. Following code will explain this.

AddHandler folderToWatch.Created, Addressof newLog
AddHandler folderToWatch.Deleted, Addressof newLog
folderToWatch.enableRaisingEvent = True

Next, write a sub procedure called newLog.

Private Sub newLog(byVal Source as Object, 
byVal evt as FileSystemEventArgs)
	If evt.ChangeType = WatcherChangeTypes.Created Then
		writeToLog(evt.fullPath,"Created")
	else if evt.ChangeType = WatcherChangeTypes.Deleted
  		writeToLog(evt.fullPath,"Deleted")
	End if
End Sub

Private Sub writeToLog(byVal filePath as String, 
byVal fileManip as String)
	Dim evtLog as new EventLog()
	If not evtLog.sourceExists("folderSPY") then
		evtLog.createEventSource
		("folderSPY", "Log of folderSPY")
	End if 
	evtLog.source = "folderSPY"
	evtLog.writeEntry
	("Folder spy Log", "File "  & filePath & " has " 
	& fileManip &  " by " & Environment.UserName.ToString,
	EventLogEntryType.Information)
End Sub

Installing the folderSPY windows service

The application that we have created is ready to test. Since it is not a traditional windows executable, you need to install it on your machine by special way. .NET Framework ships with InstallUtil.exe command line tool that installs the windows service on your machine. Before using this tool, however, we have to add an installer toy your project. This can done by right clicking your design screen and select add installer option from the menu. After you do that, you can see two more controls called ServiceProcessInstaller1 and ServiceInstaller1 added to your screen. To Change the display name of the service, open the ServiceInstaller1 control's property window and change the ServiceName property and Display name property to folderSPY (This is the service name we have given).

Since we are going to run our application on the local machine, set the account property of the ServiceProcessInstaller1 to LocalSystem. To make your service pause and continue, set the CanPauseandContinue property of your service to true. Now, compile the folderSPY application and run following command from Command Prompt:

InstallUtil <Project Path>\BIN\folderSPY.exe

If you want to uninstall the service use:

InstallUtil /U \BIN\folderSPY.exe

Running the Service

If Startup property of the service is not set to Automatic, you have to start the service manually or through some other program. To start the service open Services snap-in from the Control panel. Right click on the folderSPY service and click start.

READ MORE

Introduction

ASP.NET 2.0 offers you several ways to set a dependency between a cached item and a file(s), another cached item(s) or SQL Server database table. No doubt they satisfy most of the real world needs. However, at times the features offered by these dependencies are not sufficient. In such cases you can create your own dependency and use it instead of inbuilt ones. In this article you learn how this can be accomplished.

The Scenario

Imagine that you are developing an order processing application. The orders are received from various sources in the form of an XML file. Whenever an order is received the corresponding XML file is created on the web server. Whenever a new order is received you want some cached object to expire. At first glance you may think of setting a file based cache dependency between the new XML file and the cached object. However, there is a catch. The same folder also accepts many other XML files and you do not want to expire your item when any such files are received. Also, the names of the order files are not fixed. The only way to isolate order files from the rest of the XML files is to check the root element of the XML file. If the root element name is "order" then it is an order file and you should consider it else you need to ignore it. As you might have guessed that such logic can not be applied with the inbuilt cache dependency techniques.

The Solution

In order to tackle the above problem you need to create your own dependency. ASP.NET provides a class called CacheDependency that resides in System.Web.Caching namespace and represents the base class for all custom dependency classes. For example, the SqlCacheDependency class that represents a dependency between a cached object and SQL Server table is derived from the CacheDependency base class. The CacheDependency base class is responsible for removing an object from cache when the expiration condition is met. The CacheDependency class provides a protected method called NotifyDependencyChanged() that must be called by the inherited classes so that the dependent item gets deleted from the cache.

In our example we will create a class called MyCacheDependency that inherits from CacheDependency. Further, we will use a FileSystemWatcher to monitor the web site root folder. When any new file arrives the FileSystemWatcher will notify us by raising certain events. We will then check if the new file is an order file i.e. root element name is order. If the new file is an order file then we will call NotifyDependencyChanged() method to delete the dependent item.

Creating a custom cache dependency

To begin creating our custom cache dependency, create a new web site in Visual Studio and add a new class file called MyCacheDependency.cs in the App_Code folder. The complete source code of the class is given below:

public class MyCacheDependency:CacheDependency
{
private FileSystemWatcher watcher;

public MyCacheDependency()
{
watcher = new FileSystemWatcher
(HttpContext.Current.Request.PhysicalApplicationPath);
watcher.EnableRaisingEvents = true;
watcher.Created += new FileSystemEventHandler
(watcher_Created);
}

void watcher_Created(object sender, FileSystemEventArgs e)
{
if (Path.GetExtension(e.Name) == ".xml")
{
XmlDocument doc = new XmlDocument();
doc.Load(e.FullPath);
if (doc.DocumentElement.Name == "order")
{
base.NotifyDependencyChanged(sender, e);
}
}
}

}

Here, we created a class called MyCacheDependency that inherits from CacheDependency class. Note that the CacheDependency class resides in the System.Web.Caching namespace which must be imported at the top of your class file.

Then we declared a variable of type FileSystemWatcher. The FileSystemWatcher class residing in System.IO namespace allows you to monitor a folder for file system changes such as file creation, modification, renaming and deletion.

In the constructor of the MyCacheDependency class we set the FileSystemWatcher to monitor the root folder of the web site. We obtain physical path of the web site using PhysicalApplicationPath property of the Request object. Then we set the EnableRaisingEvents property of the FileSystemWatcher instance to true. Setting this property to true will raise several events when the monitored folder changes. We are interested to handle event related to file creation and hence we attach an event handler to the Created event of FileSystemWatcher instance.

When a new file is created on the monitored folder the FileSystemWatcher instance will raise the Created event. The event handler of Created event checks the extension of the new file. If it is an XML file (.xml) then it loads the file in an XmlDocument class. The XmlDocument class resides in the System.Xml namespace and represents the DOM parser of .NET framework. Then we check if the root element name (DocumentElement.Name) is "order" and if it is "order" then we call NotifyDependencyChanged() method of the base class CacheDependency. The NotifyDependencyChanged() method takes two parameters - sender and event argument. As the sender parameter we pass the reference of our class and as the event argument parameter we pass an empty instance of EventArgs class. Thus we send notification to CacheDependency class only if the new file is an order file.

Using the dependency

Now that we have created the custom dependency its time to use it. Add a new web form in the web site. Drag and drop a GridView control on the web form. In the Page_Load event of the web form write the following code:

protected void Page_Load(object sender, EventArgs e)
{
if (Cache["myobject"] == null)
{
string[] files=Directory.GetFiles
(Request.PhysicalApplicationPath);
MyCacheDependency cd = new MyCacheDependency();
Cache.Insert("myobject",files, cd);
}
GridView1.DataSource = (string[])Cache["myobject"];
GridView1.DataBind();
}

Here, we check if an item named myobject exist in the Cache. If it does not exist we call GetFiles() method of Directory class. The GetFiles() method returns an array of files in a specified folder. We will store this array in the cache. Then we create an instance of MyCacheDependency class and insert a new item named myobject in the cache along with the newly created dependency. The GridView control is then bound with the myobject array.

The following figure shows how the GridView looks like at run time.

image

Testing the dependency

In order to test whether our dependency is working as expected or not, create a new XML file called Order1.xml in a folder other than the web site folder. The structure of the XML file should resemble the following sample:

<?xml version="1.0" encoding="utf-8" ?>
<order>
<item>
<product>Keyboard</product>
<qty>2</qty>
</item>
<item>
<product>Mouse</product>
<qty>10</qty>
</item>
</order>

Note that the root element of the XML file is <order>. Also, create a new text file with any arbitrary text. Save both the files.

Now run the web form so that it displays a list of files as shown above. Now drag and drop the text file into the web site folder and refresh the browser window. Since we have dropped a text file the listing displayed in the grid should not change. This proves that the dependency has not yet deleted the cached object. Now drag and drop the XML file and refresh the browser window. Since we dropped an XML file and that too with <order> root element the grid will list the newly added file. This proves that the cached object was deleted and new one got created with the fresh request.

READ MORE
...