Listing 6-14 continuedPrivate _email As String End SubPublic Sub NewByVal lastName As String, _ ➝3 ByVal firstName As String, _ByVal address As String, _ByVal city As String, _ByVal stat
Trang 1Listing 6-13 (continued)
return _state;
}set{_state = value;
}}
{get{return _zipCode;
}set{_zipCode = value;
}}
{get{return _email;
}set{_email = value;
}}
{get{return _phoneNumber;
}set{_phoneNumber = value;
}}}The following paragraphs define each component of this class:
➝ 1 The class begins by defining private instance variables that are
used to hold the values associated with the class properties
By convention, each of these variable names begins with an
Trang 2underscore to indicate that it corresponds to a property with thesame name.
➝ 2 The default constructor creates a Customer object with default
values for each of its properties
➝ 3 This constructor accepts arguments that initialize the customer
data Notice that the assignment statements don’t directly assignvalues to the instance variables of the class Instead, they use theproperties to assign these values That way, any validation rou-tines written in the property setters will be used (In this example,none of the property setters have validation routines Still, it’s agood practice to follow just in case.)
➝ 4 The LastName property represents the customer’s last name Its
get routine simply returns the value of the _lastName instancevariable, and its set routine simply sets the _lastName variable
to the value passed via the value argument
➝ 5 The FirstName property represents the customer’s first name,
which is stored in the _firstName instance variable
➝ 6 The Address property represents the customer’s address, stored
in the _address instance variable
➝ 7 The City property represents the customer’s city, stored in the
_cityinstance variable
➝ 8 The State property represents the customer’s state, stored in the
_stateinstance variable
➝ 9 The ZipCode property represents the customer’s Zip code, stored
in the _zipCode instance variable
➝ 10 The Email property represents the customer’s e-mail address,
stored in the _email instance variable
➝ 11 The PhoneNumber property represents the customer’s phone
number, stored in the _phoneNumber instance variable
Listing 6-14: The Customer class (VB version)
Imports Microsoft.VisualBasicPublic Class Customer
Private _firstName As StringPrivate _address As StringPrivate _city As StringPrivate _state As StringPrivate _zipCode As StringPrivate _phoneNumber As String
(continued)
Trang 3Listing 6-14 (continued)
Private _email As String
End SubPublic Sub New(ByVal lastName As String, _ ➝3
ByVal firstName As String, _ByVal address As String, _ByVal city As String, _ByVal state As String, _ByVal zipCode As String, _ByVal phoneNumber As String, _ByVal email As String)
Me.LastName = lastNameMe.FirstName = firstNameMe.Address = addressMe.City = city
Me.State = stateMe.ZipCode = zipCodeMe.PhoneNumber = phoneNumberMe.Email = email
End Sub
GetReturn _lastNameEnd Get
Set(ByVal value As String)_lastName = valueEnd Set
End PropertyPublic Property FirstName() As String ➝5Get
Return _firstNameEnd Get
Set(ByVal value As String)_firstName = valueEnd Set
End Property
GetReturn _addressEnd Get
Set(ByVal value As String)_address = value
End SetEnd Property
Get
Trang 4Return _cityEnd Get
Set(ByVal value As String)_city = value
End SetEnd Property
GetReturn _stateEnd Get
Set(ByVal value As String)_state = value
End SetEnd Property
GetReturn _zipCodeEnd Get
Set(ByVal value As String)_zipCode = value
End SetEnd Property
GetReturn _emailEnd Get
Set(ByVal value As String)_email = value
End SetEnd PropertyPublic Property PhoneNumber() As String ➝11Get
Return _phoneNumberEnd Get
Set(ByVal value As String)_phoneNumber = valueEnd Set
End PropertyEnd Class
Creating the ShoppingCart Class
The ShoppingCart class represents the user’s virtual shopping cart, asdescribed in detail earlier in this chapter (see Table 6-5) Now, Listing 6-15presents the C# version of the ShoppingCart class, and the Visual Basic ver-sion is shown in Listing 6-16
Trang 5Listing 6-15: The ShoppingCart class (C# version)
}public List<CartItem> GetItems() ➝3{
return _cart;
}public void AddItem(string id, string name, ➝4decimal price)
{bool itemFound = false;
foreach (CartItem item in _cart){
if (item.ID == id){
item.Quantity += 1;
itemFound = true;
}}
if (!itemFound){
CartItem item =new CartItem(id, name, price, 1);
_cart.Add(item);
}}public void UpdateQuantity(int index, ➝5int quantity)
{CartItem item = _cart[index];
item.Quantity = quantity;
Trang 6{_cart.RemoveAt(index);
}
{get{return _cart.Count;
}}}The following paragraphs describe the important details of this class:
➝ 1 A private instance variable named _cart holds the contents of
the shopping cart This variable uses the new Generics feature tocreate a list object that can only hold objects of type CartItem
(For more information about generics, see the sidebar “UsingGenerics” later in this section.)
To use the List class, you must provide an imports (C#) orUsing(VB) statement that specifies the namespace System
Collections.Generic
➝ 2 The constructor for this class creates an instance of the List
class and assigns it to the _cart variable
➝ 3 The GetItems method returns a List that contains CartItem
objects It simply returns the _cart variable
➝ 4 The AddItem method adds an item to the shopping cart, using the
product ID, name, and price values passed as parameters It uses afor eachloop to search the items in the cart If one of the itemsalready in the cart has a product ID that matches the ID passed as
a parameter, that item’s quantity is incremented and a local able named itemFound is set to true If a matching item is notfound by the for each loop, a new CartItem object is createdwith a quantity of 1 Then the new cart item is added to the list
vari-➝ 5 The UpdateQuantity method changes the quantity for a
speci-fied product It uses the index value passed as a parameter toaccess the cart item, then sets the item’s Quantity property tothe value passed via the quantity parameter
➝ 6 The DeleteItem method uses the RemoveAt method of the List
class to remove the item at the index passed via the parameter
➝ 7 The Count property simply returns the Count property of the
_cartlist Notice that since this is a read-only property, no setroutine is provided
Trang 7Listing 6-16: The ShoppingCart class (VB version)
Imports Microsoft.VisualBasicImports System.Collections.GenericPublic Class ShoppingCart
_cart = New List(Of CartItem)()End Sub
Public Function GetItems() As List(Of CartItem) ➝3Return _cart
End FunctionPublic Sub AddItem(ByVal id As String, _ ➝4
ByVal name As String, _ByVal price As Decimal)Dim itemFound As Boolean = FalseFor Each item As CartItem In _cart
If item.ID = id Thenitem.Quantity += 1itemFound = TrueEnd If
Next
If Not itemFound ThenDim item As CartItemitem = New CartItem(id, name, price, 1)cart.Add(item)
End IfEnd Sub
ByVal index As Integer,ByVal quantity As Integer)Dim item As CartItem
item = _cart(index)item.Quantity = quantityEnd Sub
Public Sub DeleteItem(ByVal index As Integer) ➝6_cart.RemoveAt(index)
End SubPublic ReadOnly Property Count() As Integer ➝7Get
Return _cart.CountEnd Get
End PropertyEnd Class
Trang 8Creating the CartItem Class
The CartItem class defines an item in the user’s shopping cart TheShoppingCartclass itself (presented in the previous section) is basically alist of CartItem objects For a list of properties provided by the CartItemclass, refer to Table 6-6 Listings 6-17 and 6-18 present the C# and Visual Basicversions of this class
Using Generics
Generics is a new feature of both the C# and theVisual Basic programming languages The pur-pose of the Generics feature is to prevent acommon problem when dealing with NET col-lection classes Suppose you want to store acollection of Customer objects You can dothat by declaring an ArrayList object, thenadding Customer objects to the array list
However, nothing prevents you from addingother types of objects to the array list If youwere careless, you could also add aShoppingCartobject to the array list
With the new Generics feature, you can createcollections that are designed to hold only objects
of a specified type For example, you can create
a list that can hold only Customer objects
Then, if you try to add a ShoppingCart object
to the list by accident, an exception will bethrown
Along with the Generics feature comes anew namespace (System.Collections
Generic) with a set of collection classes thatare designed to work with the Generics feature
Here are the classes you’ll probably use most:
⻬ List: A generic array list.
⻬ SortedList: A generic list that’s kept in sorted
order
⻬ LinkedList: A generic linked list.
⻬ Stack: A generic last-in, first-out stack.
⻬ Queue: A generic first-in, first-out queue.
⻬ Dictionary: A generic collection of key/value
pairs
⻬ SortedDictionary: A generic collection of
key/value pairs kept in sorted order
The syntax for using the Generics feature takes
a little getting used to Here’s a C# example thatdefines a variable of type List whose objectsare Customer types, then creates an instance
of the list and assigns it to the variable:
List<Customer> custlist;
custlist = newList<Customer>();
Notice how the generic type is enclosed ingreater-than and less-than symbols
Here’s the same example in Visual Basic:
Dim custlist As List(OfCustomer)
custlist = New List(OfCustomer)()
As you can see, Visual Basic uses the Of word to indicate the generic type
Trang 9key-Listing 6-17: The CartItem class (C# version)
private string _name;
private decimal _price;
private int _quantity;
{this.ID = “”;
this.Name = “”;
this.Price = 0.0m;
this.Quantity = 0;
}public CartItem(string id, string name, ➝3decimal price, int quantity)
{this.ID = id;
}set{_id = value;
}}
{get{return _name;
Trang 10}set{_name = value;
}}
{get{return _price;
}set{_price = value;
}}
{get{return _quantity;
}set{_quantity = value;
}}
{get{return _price * _quantity;
}}}Here are the key points to take note of in these listings:
➝ 1 The private instance variables _id, _name, _price, and
_quantityhold the values for the cart item’s properties
➝ 2 The first constructor, which has no parameters, simply initializes
the class properties to default values
➝ 3 The second constructor lets you create a CartItem object and set
the ID, Name, Price, and Quantity properties at the same time
➝ 4 The ID property provides the ID of the product referred to by the
cart item It uses the private instance variable id to store its value
Trang 11➝ 5 The Name property represents the name of the product referred to
by the cart item It uses the private instance variable name
➝ 6 The Price property represents the price of the product It uses
the _price variable to store its value
➝ 7 The Quantity property records the quantity for the cart item It
stores its value in the _quantity variable
➝ 8 The Total property returns the value Price property multiplied
by the Quantity property Notice that this property’s value isn’tstored in an instance variable Instead, the value is recalculatedeach time it is accessed
Listing 6-18: The CartItem class (VB version)
Imports Microsoft.VisualBasicPublic Class CartItem
Private _name As StringPrivate _price As DecimalPrivate _quantity As Integer
Me.ID = “”
Me.Name = “”
Me.Price = 0.0Me.Quantity = 0End Sub
ByVal name As String, _ByVal price As Decimal, _ByVal quantity As Integer)Me.ID = id
Me.Name = nameMe.Price = priceMe.Quantity = quantityEnd Sub
GetReturn _idEnd Get
Set(ByVal value As String)_id = value
End SetEnd Property
GetReturn _name
Trang 12End GetSet(ByVal value As String)_name = value
End SetEnd Property
GetReturn _priceEnd Get
Set(ByVal value As Decimal)_price = value
End SetEnd PropertyPublic Property Quantity() As Integer ➝7Get
Return _quantityEnd Get
Set(ByVal value As Integer)_quantity = valueEnd Set
End PropertyPublic ReadOnly Property Total() As Decimal ➝8Get
Return _price * _quantityEnd Get
End PropertyEnd Class
Creating the Order Class
The Order class represents the order placed by the user Its main purpose inlife is to serve as the parameter passed to the WriteOrder method of theOrderDBclass The constructors and properties of this class appear back inTable 6-7; Listings 6-19 and 6-20 provide the C# and Visual Basic versions ofthis class
Listing 6-19: The Order class (C# version)
Trang 13private Customer _cust;
private ShoppingCart _cart;
{_cust = new Customer();
_cart = new ShoppingCart();
}
Customer Cust, ShoppingCart Cart){
}set{_orderDate = value;
}}
{get{return _cust;
}set{_cust = value;
}}
{get
Trang 14{return _cart;
}set{_cart = value;
}}
{get{decimal subTotal = 0;
foreach (CartItem item in _cart.GetItems())subTotal += item.Total;
return subTotal;
}}
{get{
if (this.Cust.State.Equals(“CA”))return this.SubTotal * 0.0775m;
elsereturn 0.0m;
}}
{get{int count = 0;
foreach (CartItem item in _cart.GetItems())count += item.Quantity;
return count * 2.00m;
}}
{get{return this.SubTotal + this.Shipping+ this.SalesTax;
}}}
Trang 15The following paragraphs draw your attention to the highlights of this class:
➝ 1 Private instance variables hold the data for the order The
_orderDatevariable holds the order’s date, while the _custand _cart variables hold the Customer and ShoppingCartobjects associated with the order
➝ 2 The parameterless constructor creates new Customer and
ShoppingCartobjects for the order
➝ 3 The second constructor lets you create an Order object by passing
the order date, customer, and shopping cart data as parameters
➝ 4 The OrderDate property lets you set or retrieve the order date
➝ 5 The Cust property lets you set or retrieve the order’s Customer
object
➝ 6 The Cart property lets you set or retrieve the order’s shopping
cart
➝ 7 The SubTotal property is a read-only property that returns the
total for the items in the order’s shopping cart It uses a foreachloop to calculate this value by adding up the Total prop-erty for each item in the shopping cart Notice that the cart’sGetItemsmethod is called to retrieve the items
➝ 8 The SalesTax property is a read-only property that calculates
the sales tax If the customer lives in California, the tax is lated at 7.75 percent Otherwise no tax is charged
calcu-In a real application, you wouldn’t hard-code the tax rate into theprogram Instead, you’d store the tax rate in a file, a database, orperhaps in the application’s web.config file That way youwouldn’t have to recompile the application when the governorreneges on that campaign promise about not raising taxes
➝ 9 The Shipping property calculates the shipping charges by
adding up the quantities for each item in the shopping cart, thenmultiplying the total number of items ordered by $2.00
Of course, hard-coding the shipping charges into the program is
an even worse idea than hard-coding the tax rate In an actualapplication, you’ll almost certainly want to choose a more flexibleway to store the shipping charges, such as in a file, a database, or
in the web.config file
➝ 10 The Total property is calculated by adding the values of the
SubTotal, Shipping, and SalesTax properties
Trang 16Listing 6-20: The Order class (VB version)
Imports Microsoft.VisualBasicImports System.Data
Public Class Order
Private _cust As CustomerPrivate _cart As ShoppingCart
_cust = New Customer()_cart = New ShoppingCart()End Sub
Public Sub New(ByVal orderDate As DateTime, _ ➝3
ByVal Cust As Customer, _ByVal Cart As ShoppingCart)Me.OrderDate = orderDate
Me.Cust = CustMe.Cart = CartEnd Sub
Public Property OrderDate() As DateTime ➝4Get
Return _orderDateEnd Get
Set(ByVal value As DateTime)_orderDate = value
End SetEnd Property
GetReturn _custEnd Get
Set(ByVal value As Customer)_cust = value
End SetEnd PropertyPublic Property Cart() As ShoppingCart ➝6Get
Return _cartEnd Get
Set(ByVal value As ShoppingCart)_cart = value
End SetEnd PropertyPublic ReadOnly Property SubTotal() As Decimal ➝7Get
(continued)
Trang 17Listing 6-20 (continued)
Dim d As Decimal = 0DFor Each item As CartItem In _cart.GetItems()
d += item.TotalNext
Return dEnd GetEnd PropertyPublic ReadOnly Property SalesTax() As Decimal ➝8Get
If Me.Cust.State = (“CA”) ThenReturn Me.SubTotal * 0.0775DElse
Return 0DEnd If
End GetEnd PropertyPublic ReadOnly Property Shipping() As Decimal ➝9Get
Dim count As Integer = 0For Each item As CartItem In _cart.GetItems()count += item.Quantity
NextReturn count * 2DEnd Get
End PropertyPublic ReadOnly Property Total() As Decimal ➝10Get
Return Me.SubTotal + Me.Shipping _+ Me.SalesTax
End GetEnd PropertyEnd Class
Creating the OrderDB Class
The last class for this application, OrderDB, contains just a single publicmethod to write an order to the database However, several private methodsare required to support this method The C# version of this class is shown inListing 6-21, and Listing 6-22 shows the Visual Basic version
Trang 18Listing 6-21: The OrderDB class (C# version)
static SqlConnection con;
public static bool WriteOrder(Order o) ➝3{
string cs = WebConfigurationManager.ConnectionStrings[“ConnectionString”]
int oNum = InsertOrder(o);
foreach (CartItem item in o.Cart.GetItems())InsertItem(item, oNum);
tran.Commit();
con.Close();
return true;
}catch (Exception ex){
tran.Rollback();
return false;
}}private static void InsertCustomer(Customer cust) ➝4{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.Transaction = tran;
try{cmd.CommandText = “INSERT INTO Customers “
(continued)
Trang 19Listing 6-21 (continued)
+ “(lastname, firstname, “+ “address, city, state, zipcode,”
+ “phone, email) “+ “VALUES (@LastName, @FirstName, “+ “@Address, @City, @State, @ZipCode,”+ “@PhoneNumber, @Email)”;
if (ex.Number == 2627) // Duplicate key{
cmd.CommandText = “UPDATE Customers “+ “SET lastname = @LastName, “+ “firstname = @FirstName, “+ “address = @Address, “+ “city = @City, “
+ “state = @State, “+ “zipcode = @ZipCode, “+ “phone = @PhoneNumber “+ “WHERE email = @Email “;
cmd.ExecuteNonQuery();
}elsethrow ex;
}}private static int InsertOrder(Order o) ➝5{
SqlCommand cmd = new SqlCommand();
Trang 20+ “shipping) “+ “VALUES (@OrderDate, @Custemail, “+ “@subtotal, @salestax, “
{SqlCommand cmd = new SqlCommand();
➝ 1 The C# version of the OrderDB class is defined with the static
keyword That simply means that the class can’t contain anyinstance properties or members Instead, all methods and proper-ties must be declared as static That’s a new feature of C# forASP.NET 2.0 Visual Basic doesn’t have this feature, which is whythe Shared keyword doesn’t appear on the class declaration for
Trang 21the VB version of the OrderDB class (This class uses static ods so that the application doesn’t have to create an instance ofthe class to use its methods for database access.)
meth-➝ 2 A pair of static (Shared in VB) variables are used to store the
SqlTransactionand SqlConnection objects used by theWriteOrdermethod The SqlTransaction object is used toplace all of the updates performed by the WriteOrder method in
a safety net so that if any of the updates fail, any updates formed up to that point are reversed And the SqlConnectionobject provides a connection to the database
per-➝ 3 The WriteOrder method is the only public method provided by the
OrderDBclass It begins by using the WebConfigurationManagerclass to retrieve the database connection string from web.config.Then it creates and opens a connection and obtains a transactionthat can be used to coordinate the updates
Next, it calls the InsertCustomer method to insert the customerdata into the Customers table, calls the InsertOrder method toinsert a row into the Orders table, and uses a for each loop tocall the InsertItem method once for each item in the order’sshopping cart Notice that the InsertOrder method returns theorder number generated for the order This value is then passed
to the InsertItem method so the order items will be associatedwith the correct order
After all of the data has been inserted, the Commit method iscalled on the transaction object to commit the updates, the con-nection is closed, and the method returns with a return value oftrueto indicate that the data was written successfully
If an exception occurs during any of the database updates, ever, the exception will be caught by the Catch statement Thenthe Rollback method of the transaction is called to reverse anyupdates that were previously made Then the WriteOrdermethod returns false so the caller knows the order was not suc-cessfully written
how-➝ 4 The InsertCustomer method inserts or updates the customer
data in the Customers table It begins by issuing the followingSQL statement to attempt to insert the customer data:
INSERT INTO Customers
(lastname, firstname,address, city, state, zipcode,phone, email)
VALUES(@LastName, @FirstName,
@Address, @City, @State, @ZipCode,
@PhoneNumber, @Email)