Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Create a Class-Collection of another Class (Extend a Class like a List<T>)

0.00/5 (No votes)
21 Sep 2014 1  
Create a Class-Collection of another Class, Extend a class like a List

Introduction

In this article we will talk about the Class Collection in C#, Sometime in the application we don't need to retrieve data from database so often. For an example we have a used car database and we would like to filter data according to different parameter. In this situation we will get the all of vehicles from database and saved in the collection and then we will put filter in the collection according to our need.

Sometimes user wants to filter collection according to make or model or according to the condition of vehicle or by mileage and so on.

What practice would be the best for this situation? In my opinion class collection of another class will be the best solution of it rather than making a different method in the base class for each condition.

When I say Class-Collection of another class, it would be like something below, where Vehicle is base class and CollectionVehicle class is derived Class of List<t> in this case List<Vehicle>

public class CollectionVehicle : List<Vehicle>
	
{
	
}

Here class Vehicle is the base class, it will hold all the property of the Vehicle object. We are not defining any method inside the base class. But in the collection class we will have the methods like below.

public VehicleCollection GetVehicleByModel(string model)
{
        return new VehicleCollection();
}
public VehicleCollection GetVehilceByMakeAndmodel(string make, string model)
{
        return new VehicleCollection();
}

Now we need to add some more methods like below so that we can get the Vehicle according to Condition or mileage. Neither we  want to add any more method in our base class it might impact our existing system nor we want to make another derived class.

public VehicleCollection GetVehicleByCondition(string condition)
{
        return new VehicleCollection();
}
public VehicleCollection GetVehicleByMileage(int mileage)
{
	return new VehicleCollection();
}

Another good thing of doing it we only put filer in the class collection we don’t need to write the queries to fetch the data from database.

I have used VS2012 and MS-SQL 2008R2 database for this project. I am using database from this article

http://www.codeproject.com/Tips/806562/Create-Table-and-Stored-Procedure-in-SQL-Server-an

Read above article for database connection and retrieve data from database.Here is the Stored Procedure "GetVehicles", which we will use in this project. It returns all the vehicles form database

USE [UsedCarManagement]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER  PROCEDURE [dbo].[GetVehicles]

AS
BEGIN
	SELECT vh.ID, vh.Year,vh.Make,vh.Model,vh.Color,vh.Trim,vh.Condition,vh.Mileage,vh.VINumber,vh.ModifiedDate,
		vh.IsHold, vh.Note
	FROM dbo.Vehicle vh
	
END

Let's Create a Project in VS 2012

Open VS and select File->New->ASP.NET Web Forms Application and  call it  ClassCollectionTest. Once you create a project lets create a MasterPage.  Right Click on project solution and Create a MasterPage and call it MainMasterPage. Create a Start.Aspx page which used MainMaster.Master page as layout page.  Here we are loading data into list which is defined in master page therefore content page should use masterpage. Lets create a New Folder and call it Model we will keep all of our classes under this folder. We will create  two classes  Vechile.cs and  VehicleCollection.cs where VehicleCollection is derived from List<Vehicle>.

So far we have created MainMaterPage.Master page, Start.aspx page which using MainMaterpage and two classes.  Your project solution will look like as below Fig 1

Fig 1

Here is the Vehicle.cs class code

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

namespace ClassCollectionTest.Model
{
	public class Vehicle
	{
		private int _id;
		private string _year;
		private string _make;
		private string _model;
		private string _color;
		private string _trim;
		private string _condition;
		private int _mileage;
		private string _vinnumber;
		private bool? _isHold;
		private string _note;
		private DateTime _dateModified;

		/// <summary>
		/// Gets or sets the ID of Vehicle
		/// </summary>
        public int ID
		{
			get { return this._id; }
			set { this._id = value; }
		}
        /// <summary>
        /// Gets or set the Year of Vehicle
        /// </summary>
		public string Year
		{
			get { return this._year; }
			set { this._year = value; }
		}
        /// <summary>
        /// Gets or sets the Make of Vehicle
        /// </summary>
		public string Make
		{
			get { return this._make; }
			set { this._make = value; }
		}
        /// <summary>
        /// Gets or sets the Model of Vehicle
        /// </summary>
		public string Model
		{
			get { return this._model; }
			set { this._model = value; }
		}
        /// <summary>
        /// Gets or sets the Color of Vehicle
        /// </summary>
		public string Color
		{
			get { return this._color; }
			set { this._color = value; }
		}
        /// <summary>
        /// Gets or sets the Trim Vehicle
        /// </summary>
		public string Trim
		{
			get { return this._trim; }
			set{ this._trim = value;}
		}
        /// <summary>
        /// Gets or sets the Condition of Vehicle
        /// </summary>
		public string Condition
		{
			get { return this._condition; }
			set { this._condition = value; }
		}
        /// <summary>
        /// Gets or sets the Mileage of Vehicle
        /// </summary>
		public int Mileage
		{
			get { return this._mileage; }
			set { this._mileage = value; }
		}
        /// <summary>
        /// Gets or sets the VINumber or Vehicle
        /// </summary>
		public string VINumber
		{
			get { return this._vinnumber; }
			set { this._vinnumber = value; }
		}
        /// <summary>
        /// Gets or sets the IsHold of Vehicle
        /// </summary>
		public bool? Ishold
		{
			get { return this._isHold; }
			set { this._isHold = value; }
		}
        /// <summary>
        /// Gets or sets the Note of Vehicle
        /// </summary>
		public string Note
		{
			get { return this._note; }
			set { this._note = value; }
		}
        /// <summary>
        /// Gets or sets the Modified Date of Vehicle
        /// </summary>
		public DateTime DateModified
		{
			get { return this._dateModified; }
			set { this._dateModified = value; }
		}
	}
}

Vehicle.cs class has only get and set method for each property.

Here is the code for VehicleCollection.cs

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


namespace ClassCollectionTest.Model
{
	public class VehicleCollection : List<Vehicle>
	{
        /// <summary>
        /// A collection of Vehicle  data
        /// </summary>
		public VehicleCollection()
		{
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="VehicleCollection"/> class.
        /// </summary>
        /// <param name="vehilces">
        /// A collection of <see cref="Vehicle"/> objects to initialize the collection with.
        /// </param>
		public VehicleCollection(IEnumerable<Vehicle> vehilces) : base(vehilces)
		{
		}
        /// <summary>
        /// Gets of list of Vehicles for uses
        /// </summary>
        /// <param name="vinnumber"></param>
        /// <returns>A Collection of Vehilces </returns>
		public VehicleCollection GetVehicleByVINumber(string vinnumber)
		{
			return new VehicleCollection(this.Where(vh => vh.VINumber == vinnumber));
		}
        /// <summary>
        /// Gets of list of Vehicles for uses
        /// </summary>
        /// <param name="make"></param>
        /// <returns>A Collection of Vehilces </returns>
		public VehicleCollection GetVehicleByMake(string make)
		{	return new VehicleCollection(this.Where(vh => vh.Make == make));
		
		}

        //public VehicleCollection GetVehicleByMakeAndMdeol(string make, string model)
        //{
        //    return new VehicleCollection(this.Where(vh => vh.Make == make & vh.Model==model));
        //}
	}
}

Lets talk about the VehicleCollection.cs class. First we have defined a constructor as

public VehicleCollection()
		{
		}

Then we make our VehicleCollection collection as IEnumerable

public VehicleCollection(IEnumerable<Vehicle> vehilces) : base(vehilces)
		{
		}

We have defined a method which takes an input paramter vinnumber and  which retuns  "VehicelCollection"

	public VehicleCollection GetVehicleByVINumber(string vinnumber)
		{
			return new VehicleCollection(this.Where(vh => vh.VINumber == vinnumber));
		}

Input parameter is used  as filter in the VehicleCollection as you can see as it is used like a Lamda expression above. This method returns the  VehicleCollection which VinNumber match with input parameter. Similarlly I have defined another method GetVehicleByMake() and GentVehicleByMakeAndModel() but GentVehicleByMakeAndModel is not used in this project.

GetVehicleByMakeAndMdeol()

Before we use the method we have to fill the data into VehicleCollection. In the master page we will fill out VehicleCollection so that this will avaliable in the whole application.

We have created a MaterPage lets use it.

MainMasterPage.aspx

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MainMasterPage.master.cs" Inherits="ClassCollectionTest.MainMasterPage" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

and MainMasterPage.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using ClassCollectionTest.Model;

namespace ClassCollectionTest
{
	public partial class MainMasterPage : System.Web.UI.MasterPage
	{
		// CollectionOfVehicle variable declare to hold the VehicleCollection type data

        public VehicleCollection CollectionOfVehicle;

		protected void Page_Load(object sender, EventArgs e)
		{
			this.CollectionOfVehicle= this.GetAllVehicles();
		}

		// get the data from database and put into VehicleCollection
		private VehicleCollection GetAllVehicles()
		{
			string connStr = ConfigurationManager.ConnectionStrings["vehicleConString"].ConnectionString;
			SqlConnection objSqlConn = new SqlConnection(connStr);
			List<Vehicle> listVehicle = new List<Vehicle>();
			try
			{
				objSqlConn.Open();
				SqlCommand command = new SqlCommand("GetVehicles", objSqlConn);
				command.CommandType = CommandType.StoredProcedure;
				SqlDataAdapter adapter = new SqlDataAdapter(command);
				DataSet ds = new DataSet();
				adapter.Fill(ds, "tb1");	
								
				if (ds.Tables[0].Rows.Count > 0)
				{
					for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
					{
						Vehicle vehicle = new Vehicle();
						vehicle.ID = Convert.ToInt32(ds.Tables[0].Rows[i]["ID"]);
						vehicle.Year = ds.Tables[0].Rows[i]["Year"].ToString();
						vehicle.Make = ds.Tables[0].Rows[i]["Make"].ToString();
						vehicle.Model = ds.Tables[0].Rows[i]["Model"].ToString();
						vehicle.Color = ds.Tables[0].Rows[i]["Color"].ToString();
						vehicle.Trim = ds.Tables[0].Rows[i]["Trim"].ToString();
						vehicle.Condition = ds.Tables[0].Rows[i]["Condition"].ToString();
						vehicle.Mileage = Convert.ToInt32(ds.Tables[0].Rows[i]["Mileage"]);
						vehicle.VINumber = ds.Tables[0].Rows[i]["VINumber"].ToString();
						vehicle.DateModified = Convert.ToDateTime(ds.Tables[0].Rows[i]["ModifiedDate"].ToString());
						vehicle.Ishold = ds.Tables[0].Rows[i]["isHold"] != DBNull.Value ? Convert.ToBoolean(ds.Tables[0].Rows[i]["isHold"]) : false;					
						vehicle.Note = ds.Tables[0].Rows[i]["Note"].ToString(); ;
						listVehicle.Add(vehicle);
						
					}				
				}				

			}
			catch (Exception ex)
			{
				// if you want to log the error, you can log before you redirect 
				Response.Redirect("Error.aspx?error=" + ex.Message.ToString());
			}
			finally
			{
				objSqlConn.Close();				
			}


			return listVehicle == null ? new VehicleCollection() : new VehicleCollection(listVehicle);
		}
	}
}

In the code behind of Master page we have defined a public VehicleCollection CollectionOfVehicle variable which is a List/Collection because and its type is VehicleCollection and VehicleCollection is a list/collection own itself. Then we have defined a private method private VehicleCollection GetAllVehicles() where we have got the data from database and put date into VehicleCollection list/collection. In Page_Load() method we have assigned the VehicleCollection data to CollectionOfVehicle this way we have got all the vehicles into CollectionOfVehicle object.

we have returned the VehicleCollection  from private method even if list is empty. We don't want to return null if list is empty but we want to get zero if list is empty therefore we have used below if else condition.

return listVehicle == null ? new VehicleCollection() : new VehicleCollection(listVehicle);

Now we have a data in the VehicleCollection list/collection and CollectionOfVehicle collection.

Let's create Start.aspx page and we will comsume below method from this page

public VehicleCollection GetVehicleByMake(string make)
		{	return new VehicleCollection(this.Where(vh => vh.Make == make));
		
		}

Start.aspx page mark up is below

<%@ Page Title="" Language="C#" MasterPageFile="~/MainMasterPage.Master" AutoEventWireup="true" CodeBehind="Start.aspx.cs" Inherits="ClassCollectionTest.Start" %>
<%@ MasterType VirtualPath="~/MainMasterPage.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div id="mainContentDiv">
        <asp:Label ID="lblMake" runat="server" Text="Make"></asp:Label>   
        <asp:TextBox ID="txtMake" runat="server"></asp:TextBox> <br /><br />
        <asp:Button ID="btnGetByMake" runat="server" Text="Get By Make" OnClick="btnGetByMake_Click" /> <br /><br />

        <asp:GridView ID="gvDisplay" runat="server">
        </asp:GridView>
    </div>
</asp:Content>

This page has a text box to enter the "Make" of vehicle and one GridView to display the output result. There is a button and button event which pulls the data from

CollectionOfVehicle()

Lets look the code behind of this page. we have not retrived the data from database instead of that we have pulled the data from CollectionOfVehicle object which we declared at the MaterPage. This varaible's datatype is VehicleCollection class therefore  CollectionOfVehicle object gets all the methdod and property of VehicleCollection Class thats why it has a Method and other property which we declred in the VehicleCollection class.  Look at below how we have called the GetVehicleByMake( ) method.

var vehicles = Master.CollectionOfVehicle.GetVehicleByMake(txtMake.Text.Trim());

We have not called method like below because VehicleCollection is not a variable of MasterPage, it is just a template object/class which holds the method and template. If we use like below it will throw an error.

var vehicles = Master.VehicleCollection.GetVehicleByMake(txtMake.Text.Trim());

Start.aspx.cs code is below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using ClassCollectionTest.Model;

namespace ClassCollectionTest
{
	public partial class Start : System.Web.UI.Page
	{
		protected void Page_Load(object sender, EventArgs e)
		{

		}		

		protected void btnGetByMake_Click(object sender, EventArgs e)
		{
			var vehicles = Master.CollectionOfVehicle.GetVehicleByMake(txtMake.Text.Trim());

			gvDisplay.DataSource = vehicles;
			gvDisplay.DataBind();
			//string x = "";
		}
	}
}

Your start page output will look like as below Fig 2.

Fig2

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here