The Object Class

Introduction

To support any type of value, the C# language provides a type named object. Therefore, use it to declare a variable for any type. After declaring the variable, you can set an appropriate value to it based on how you want to use the variable.

To support values of any type, the .NET Framework provides a class named Object. This is the ancestor to all classes of the .NET Framework. It is also the ancestor to any class you create in your application. As a result, whenever you create a class in your application, it is automatically derived from Object. If you want, you can still explicitly create a class based on Object.

The Object class is defined in the System namespace. As the ancestor to all classes, the Object class provides some common functionalities that can be useful to all classes.

Practical LearningPractical Learning: Introducing Ancestor Classes

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New -> Project...
  3. In the middle list, click Empty Project (.NET Framework)
  4. Change the Name to WaterDistributionCompany1
  5. Press Enter
  6. To create a new class, in the Class View, right-click WaterDistributionCompany1 -> Add -> Class...
  7. Set the Name to Customer and click Add
  8. Change the file as follows:
    namespace WaterDistributionCompany1
    {
        public class Customer
        {
            
        }
    }
  9. In the document, right-click insde the constructor -> Snippet -> Insert Snippet...
  10. Double-click Visual C# and doble-click propfull

    Code Snippet - Full Property

    using System;
    
    namespace WaterDistributionCompany1
    {
        public class Customer : Object
        {
            private int myVar;
    
            public int MyProperty
            {
                get { return myVar; }
                set { myVar = value; }
            }
    
        }
    }
  11. Change the class as follows:
    using System;
    
    namespace WaterDistributionCompany1 : Object
    {
        public class Customer
        {
            public string AccountNumber { get; set; }
            public string FirstName     { get; set; }
            public string LastName      { get; set; }
    
            public Customer(string acntNumber = "", string firstName = "", string lasName = "")
            {
                AccountNumber = acntNumber;
                FirstName     = firstName;
                FirstName     = lasName;
            }
        }
    }
  12. n the Solution Explorer, right-click WaterDistributionCompany1 -> Add -> Class...
  13. Type WaterBill as the name of the class
  14. Click Add
  15. Change the class as follows:
    namespace WaterDistributionCompany1
    {
        public class WaterBill
        {
            public int    BillNumber          { get; set; }
            public string AccountNumber       { get; set; }
            public int    BillingDays         { get; set; }
            public double CounterReadingStart { get; set; }
            public double CounterReadingEnd   { get; set; }
            public double TotalHCF            { get { return CounterReadingEnd - CounterReadingStart; } }
            public double TotalGallons        { get { return (CounterReadingEnd - CounterReadingStart) * 748.05; } }
    
            public double First15HCF
            {
                get {
                    if (TotalHCF <= 15.00)
                    {
                        return TotalHCF * 3.612;
                        
                    }
                    else // if (TotalHCF <= 25.00)
                    {
                        return 15.00 * 3.612;
                    }
                }    
            }
    
            public double Next10HCF
            {
                get
                {
                    if (TotalHCF <= 15.00)
                    {
                        return 0.00;
                    }
                    else if (TotalHCF <= 25.00)
                    {
                        return (TotalHCF - 15.00) * 3.918;
                        
                    }
                    else
                    {
                        return 10.00 * 3.918;
                    }
                }
            }
            public double RemainingHCF
            {
                get
                {
                    if (TotalHCF <= 25.00)
                    {
                        return 0.00;
                    }
                    else
                    {
                        return (TotalHCF - 25.00) * 2.2763;
                    }
                }
            }
    
            public double WaterUsageCharges => First15HCF + Next10HCF + RemainingHCF;
            public double SewerCharges      => WaterUsageCharges * 0.252;
            public double StormCharges      => WaterUsageCharges * 0.0025;
            public double TotalCharges      => WaterUsageCharges + SewerCharges + StormCharges;
            public double LocalTaxes        => TotalCharges * 0.005;
            public double StateTaxes        => TotalCharges * 0.0152;
    	    public double  AmountDue        => TotalCharges + LocalTaxes + StateTaxes;
            public double LateAmountDue     => AmountDue + 8.65;
        }
    }
  16. To create a new class, in the Class View, right-click WaterDistributionCompany1 -> Add -> Class...
  17. Type WaterDistributionCompany as the name of the class
  18. Click Add
  19. Change the document as follows:
    using static System.Console;
    
    namespace WaterDistributionCompany1
    {
        public class WaterDistributionCompany
        {
            private static Customer CreateAccount()
            {
                Customer client = new Customer();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Type the following pieces of information about the customer");
                Write("Account Number: ");
                client.AccountNumber = ReadLine();
                Write("First Name:     ");
                client.FirstName = ReadLine();
                Write("Last Name:      ");
                client.LastName = ReadLine();
    
                return client;
            }
    
            private static void Display(WaterBill bill)
            {
                WriteLine("Water Distribution Company");
                WriteLine("Bill Preparation");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0}", bill.InvoiceNumber);
                WriteLine("Account #: {0}", bill.AccountNumber);
                WriteLine("-----------------------------------");
                WriteLine("Billing Days: {0}", bill.BillingDays);
                WriteLine("Counter Reading Start: {0}", bill.CounterReadingStart);
                WriteLine("Counter Reading End: {0}", bill.CounterReadingEnd);
                WriteLine("-----------------------------------");
                WriteLine("Total HCF: {0}", bill.TotalHCF);
                WriteLine("Total Gallons: {0}", bill.TotalGallons);
                WriteLine("First 15 HCF: {0}", bill.First15HCF);
                WriteLine("Next 10 HCF: {0}", bill.Next10HCF);
                WriteLine("Remaining HCF: {0}", bill.RemainingHCF);
                WriteLine("Water Usage Charges: {0}", bill.WaterUsageCharges);
                WriteLine("Water Usage Charges: {0}", bill.WaterUsageCharges);
                WriteLine("Sewer Charges: {0}", bill.SewerCharges);
                WriteLine("Storm Charges: {0}", bill.StormCharges);
                WriteLine("Total Charges: {0}", bill.TotalCharges);
                WriteLine("Local Taxes: {0}", bill.LocalTaxes);
                WriteLine("State Taxes: {0}", bill.StateTaxes);
                WriteLine("Amount Due: {0}", bill.AmountDue);
                WriteLine("Late Amount Due: {0}", bill.LateAmountDue);
                WriteLine("=====================================");
            }
            public static int Main()
            {
                WaterBill wb = new WaterBill();
    
                wb.InvoiceNumber = 621856;
    
                Customer cust = CreateAccount();
                wb.AccountNumber = cust.AccountNumber;
    
                Clear();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0}", wb.InvoiceNumber);
                WriteLine("Customer Account #: {0}", cust.AccountNumber);
                WriteLine("-----------------------------------");
                Write("Type the number of cycling days: ");
                wb.BillingDays = int.Parse(ReadLine());
                Write("Counter Reading Start:           ");
                wb.CounterReadingStart = int.Parse(ReadLine());
                Write("Counter Reading End:             ");
                wb.CounterReadingEnd = int.Parse(ReadLine());
    
                Clear();
    
                Display(wb);
    
                return 0;
            }
        }
    }
  20. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Type the following pieces of information about the customer
    Account Number:
  21. Type the customer information as follows:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Type the following pieces of information about the customer
    Account Number: 7518-302-6895
    First Name:     Grace
    Last Name:      Brenner
  22. Press Enter
    Water Distribution Company
    Water Bill
    -----------------------------------
    Invoice #: 621856
    Customer Account #: 7518-302-6895
    -----------------------------------
    Type the number of cycling days:
  23. For the water bill information, type some values as follows:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Invoice #: 621856
    Customer Account #: 7518-302-6895
    -----------------------------------
    Type the number of cycling days: 163
    Counter Reading Start:           96
    Counter Reading End:             114
  24. Press Enter:
    Water Distribution Company
    Bill Preparation
    -----------------------------------
    Invoice #: 621856
    Account #: 7518-302-6895
    -----------------------------------
    Billing Days: 163
    Counter Reading Start: 96
    Counter Reading End: 114
    -----------------------------------
    Total HCF: 18
    Total Gallons: 13464.9
    First 15 HCF: 54.18
    Next 10 HCF: 11.754
    Remaining HCF: 0
    Water Usage Charges: 65.934
    Water Usage Charges: 65.934
    Sewer Charges: 16.615368
    Storm Charges: 0.164835
    Total Charges: 82.714203
    Local Taxes: 0.413571015
    State Taxes: 1.2572558856
    Amount Due: 84.3850299006
    Late Amount Due: 93.0350299006
    =====================================
    Press any key to continue . . .
  25. Press Enter to close the window and return to your programming environment

Displaying an Object

To let you display an object to the console screen, both the Console.Write() and the Console.WriteLine() methods each has a syntax that takes an object argument. Their syntaxes are:

public static void Write(double value);
public static void WriteLine(double value);

Equality of Two Class Variables

When you declare and initialize two variables, one of the operations you may want to subsequently perform is to compare their values. To support this operation, the Object class provides its children with a method named Equals. The data types we have used so far (int and double) are already equipped for this method.

The Object.Equals() method comes in two versions. The first has the following syntax:

public virtual bool Equals(object obj);

This version allows you to call the Object.Equals() method on a declared variable and pass the other variable as argument. Here is an example:

using System;

class BookCollection
{
    static void Main()
    {
	// First book
	int numberOfPages1 = 422;
	// Second book
	int numberOfPages2 = 858;
	// Third book
	int numberOfPages3 = 422;

	if( numberOfPages1.Equals(numberOfPages2) == true )
  	    Console.WriteLine("The first and the second books have the same number of pages");
	else
  	    Console.WriteLine("The first and the second books have different number of pages");
			
	if( numberOfPages1.Equals(numberOfPages3) == true )
  	    Console.WriteLine("The first and the third books have the same number of pages");
	else
  	    Console.WriteLine("The first and the third books have different number of pages");
    }
}

This would produce:

The first and the second books have different number of pages
The first and the third books have the same number of pages

The first version of the Object.Equals method is declared as virtual, which means you can override it if you create your own class. The second version of the Object.Equals() method is:

public static bool Equals(object obj2, object obj2);

As a static method, to use it, you can pass the variables of two classes whose values you want to compare.

In both cases, if the values of the variables are similar, the Equals() method returns true. If they are different, the method returns false.

Overriding an Equality

If you are using the Equals()b> method to compare the variables of two primitive types, the comparison should be straight forward. If you want to use this methods on variables declared from your own class, you should provide your own implementation of this method.

To override the Equals()b> method, in your class, create a body for the method. In the body of that method, create a conditional statement that compares a locally declared variable to the argument, and then return the Boolean reason. Here is an example:

using System;

namespace BusinessDistribution
{
    public class Customer : Object
    {
        private string acnt;
        private string fn;

        public Customer(string number = "", string name = "")
        {
            acnt = number;
            fn = name;
        }

        public string AccountNumber
        {
            get { return acnt; }
            set { acnt = value; }
        }

        public string FullName
        {
            get { return fn; }
            set { fn = value; }
        }

        public override bool Equals(object obj)
        {
            Customer cust = (Customer)obj;

            if( (acnt == cust.acnt) &&
                (fn == cust.fn) )
                return true;

            return false;
        }
    }
}

An object of the class can be tested as follows:

using System;

namespace BusinessDistribution
{
    public class Exercise
    {
        public static int Main()
        {
            var first = new Customer("72-975947-64", "James Barans");
            var second = new Customer("50-315759-95", "Paul Motto");
            var third = new Customer("72-975947-64", "James Barans");

            if (first.Equals(second))
            {
                Console.Write("The first and the second records ");
                Console.WriteLine("represent the same customer.");
            }
            else
                Console.WriteLine("The first and the second records are different.");

            if (first.Equals(third))
            {
                Console.Write("The first and the third records ");
                Console.WriteLine("represent the same customer");
            }
            else
                Console.WriteLine("The first and the third records are different.");;

            return 0;
        }
    }
}

This would produce:

he first and the second records are different.
he first and the third records represent the same customer
ress any key to continue . . .

Practical LearningPractical Learning: Converting to String

  1. Access the Customer.cs file
  2. To implement and use a ToString() method, change the file as follows:
    using System;
    
    namespace WaterDistributionCompany1
    {
        public class Customer : Object
        {
            public string AccountNumber { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
            public Customer(string acntNumber = "", string firstName = "", string lasName = "")
            {
                AccountNumber = acntNumber;
                FirstName = firstName;
                FirstName = lasName;
            }
    
            public override bool Equals(object obj)
            {
                Customer cust = (Customer)obj;
    
                if( AccountNumber == cust.AccountNumber )
                    return true;
    
                return false;
            }
        }
    }

Hash Codes

If you create a list of objects where each object is from your class (a class you have created). You must provide a mechanism that makes it easy to find an object from that list. One way to do this is to use a significant or helpful number that is associated with the object. The mechanism you use to perform this operation is referred to as a has code.

To assist you in creating a hash code, the Object class is equipped with an overridable method named GetHashCode. Its syntax is:

public virtual int GetHashCode();

Because we haven't studied lists (and collections), we are not really interested in the details of this method. Still, if you decide to override the ToString() method, the .NET Framework also wants you to override the Object.GetHashCode() method. At a minimum, you can simply provide some default behavior.

Practical LearningPractical Learning: Introducing the Hash Code

  1. Click below the closing curly bracket of the ToString() method and type over
  2. In the list of the Intellisence, double-click override and press Space
  3. In the short list that appears, double-click GetHashCode()
    using System;
    
    namespace WaterDistributionCompany1
    {
        public class Customer : Object
        {
            public string AccountNumber { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
            public Customer(string acntNumber = "", string firstName = "", string lasName = "")
            {
                AccountNumber = acntNumber;
                FirstName = firstName;
                FirstName = lasName;
            }
    
            public override bool Equals(object obj)
            {
                Customer cust = (Customer)obj;
    
                if( AccountNumber == cust.AccountNumber )
                    return true;
    
                return false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }

Values and Strings

Introduction

To let you convert a value, practically any value, to a string, the Object class is equipped with a method named ToString. It syntax is:

public virtual string ToString();

As you can see, this is a virtual method, meaning the descendants of the Object class, which includes all classes, have the choice to override it. As a matter of facts, all of the primitive data types such as int and double provide their versons of this method.

When presenting a primitive value to the user, you can convert that value to a string by applying to ToString to it. You can also convert an expression to a string the same way. Here are examples:

using static System.Console;

public class Exercise
{
    public static void Main()
    {
        var emplName = "Judith Mermoz";
        string hourlySalary = 22.74.ToString();
        string timeWorked = 36.60.ToString();
        string netPay = (22.74 * 36.60).ToString();

        WriteLine("Full Name:     " + emplName);
        WriteLine("Hourly Salary: " + hourlySalary);
        WriteLine("Weekly Salary: " + netPay);
        WriteLine("==============================");
    }
}

This would produce:

Full Name:     Judith Mermoz
Hourly Salary: 22.74
Weekly Salary: 832.284
==============================
Press any key to continue . . .

When using a variable in the parentheses of the Write() or the WriteLine() methods, although those methods "understand" the meaning of every primitive value, you can still convert the variable to string. Here is an example:

using System;

class BookCollection
{
    static int Main()
    {
	int numberOfPages = 422;
	
        Console.WriteLine("Number of Pages: {0}", numberOfPages.ToString());
	return 0;
    }
}

In fact in some cases, you will have to perform that conversion.

Practical LearningPractical Learning: Converting to String

  1. To convert some values to string, change the document as follows:
    using static System.Console;
    
    namespace WaterDistributionCompany1
    {
        public class WaterDistributionCompany
        {
            private static Customer CreateAccount()
            {
                Customer client = new Customer();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Type the following pieces of information about the customer");
                Write("Account Number: ");
                client.AccountNumber = ReadLine();
                Write("First Name:     ");
                client.FirstName = ReadLine();
                Write("Last Name:      ");
                client.LastName = ReadLine();
    
                return client;
            }
    
            private static void Display(WaterBill bill)
            {
                WriteLine("Water Distribution Company");
                WriteLine("Bill Preparation");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0}", bill.InvoiceNumber);
                WriteLine("Account #: {0}", bill.AccountNumber);
                WriteLine("-----------------------------------");
                WriteLine("Billing Days: {0}", bill.BillingDays);
                WriteLine("Counter Reading Start: {0}", bill.CounterReadingStart);
                WriteLine("Counter Reading End: {0}", bill.CounterReadingEnd);
                WriteLine("-----------------------------------");
                WriteLine("Total HCF: {0}", bill.TotalHCF.ToString());
                WriteLine("Total Gallons: {0}", bill.TotalGallons.ToString());
                WriteLine("First 15 HCF: {0}", bill.First15HCF.ToString());
                WriteLine("Next 10 HCF: {0}", bill.Next10HCF.ToString());
                WriteLine("Remaining HCF: {0}", bill.RemainingHCF.ToString());
                WriteLine("Water Usage Charges: {0}", bill.WaterUsageCharges.ToString());
                WriteLine("Water Usage Charges: {0}", bill.WaterUsageCharges.ToString());
                WriteLine("Sewer Charges: {0}", bill.SewerCharges.ToString());
                WriteLine("Storm Charges: {0}", bill.StormCharges.ToString());
                WriteLine("Total Charges: {0}", bill.TotalCharges.ToString());
                WriteLine("Local Taxes: {0}", bill.LocalTaxes.ToString());
                WriteLine("State Taxes: {0}", bill.StateTaxes.ToString());
                WriteLine("Amount Due: {0}", bill.AmountDue.ToString());
                WriteLine("Late Amount Due: {0}", bill.LateAmountDue.ToString());
                WriteLine("=====================================");
            }
    
            public static int Main()
            {
                WaterBill wb = new WaterBill();
    
                wb.InvoiceNumber = 806277;
    
                Customer cust = CreateAccount();
                wb.AccountNumber = cust.AccountNumber;
    
                Clear();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0}", wb.InvoiceNumber);
                WriteLine("Customer Account #: {0}", cust.AccountNumber);
                WriteLine("-----------------------------------");
                Write("Type the number of cycling days: ");
                wb.BillingDays = int.Parse(ReadLine());
                Write("Counter Reading Start:           ");
                wb.CounterReadingStart = int.Parse(ReadLine());
                Write("Counter Reading End:             ");
                wb.CounterReadingEnd = int.Parse(ReadLine());
    
                Clear();
    
                Display(wb);
    
                return 0;
            }
        }
    }
  2. To execute the program and test it, on the main menu, click Debug -> Start Without Debugging
  3. Type some values as follows:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Type the following pieces of information about the customer
    Account Number: 4820-375-2842
    First Name:     Akhil
    Last Name:      Koumari
  4. Press Enter
    Water Distribution Company
    Water Bill
    -----------------------------------
    Invoice #: 806277
    Customer Account #: 4820-375-2842
    -----------------------------------
    Type the number of cycling days:
  5. Type some values as follows:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Invoice #: 806277
    Customer Account #: 4820-375-2842
    -----------------------------------
    Type the number of cycling days: 34
    Counter Reading Start:           109992
    Counter Reading End:             109998
  6. Press Enter
    Water Distribution Company
    Bill Preparation
    -----------------------------------
    Invoice #: 806277
    Account #: 4820-375-2842
    -----------------------------------
    Billing Days: 34
    Counter Reading Start: 109992
    Counter Reading End: 109998
    -----------------------------------
    Total HCF: 6
    Total Gallons: 4488.3
    First 15 HCF: 21.672
    Next 10 HCF: 0
    Remaining HCF: 0
    Water Usage Charges: 21.672
    Water Usage Charges: 21.672
    Sewer Charges: 5.461344
    Storm Charges: 0.05418
    Total Charges: 27.187524
    Local Taxes: 0.13593762
    State Taxes: 0.4132503648
    Amount Due: 27.7367119848
    Late Amount Due: 36.3867119848
    =====================================
    Press any key to continue . . .
  7. Press Enter to close the DOS window and return to your programming environment

Number Formatting

To properly display data in a friendly and most familiar way, you can format it. Formatting tells the compiler what kind of data you are using and how you want the compiler to display it to the user. As it happens, you can display a natural number in a common value or else. When it comes to double-precision numbers, you may want to display a distance with three values on the right side of the decimal separator and in some cases, you may want to display a salary with only 2 decimal places.

The System namespace provides a specific letter that you can use in the Write() or WriteLine()'s placeholder for each category of data to display. To format a value, in the placeholder of the variable or value, after the number, type a colon and one of the appropriate letters from the following table. If you are using ToString(), then, in the parentheses of ToString(), you can include a specific letter or combination inside of double-quotes. The letters and their meanings are:

Character Description
c C Currency values
d D Decimal numbers
e E Scientific numeric display such as 1.45e5
f F Fixed decimal numbers
d D General and most common type of numbers
n N Natural numbers
r R Roundtrip formatting
s S Hexadecimal formatting
p P Percentages

Here are examples:

using static System.Console;

public class Exercise
{
    public static void Main()
    {
        var Distance = 248.38782;
        var age = 15;
        var NewColor = 3478;
        var hSalary = 22.74;
        var HoursWorked = 35.5018473;
        var WeeklySalary = hSalary * HoursWorked;

        WriteLine("Distance: {0}", Distance.ToString("E"));
        WriteLine("Age: {0}", age.ToString());
        WriteLine("Color: {0}", NewColor.ToString("X"));
        WriteLine("Weekly Salary: {0} for {1} hours",
                          WeeklySalary.ToString("c"),
              		  HoursWorked.ToString("F"));

        WriteLine();
    }
}

This would produce:

Distance: 2.483878E+002
Age: 15
Color: D96
Weekly Salary: $807.31 for 35.50 hours

As you might have noticed, if you leave the parentheses of ToString() empty, the compiler would use a default formatting to display the value.

As opposed to calling ToString(), you can use the above letters in the curly brackets of the first part of the Write() or the WriteLine() methods. In this case, after the number in the curly brackets, type the colon operator followed by the letter.

Line Formatting

So far, to position text of different lengths, we had to "corrupt" a string by including extra-empty spaces. Such a technique can be uncertain at times. Fortunately, you can highly format how a string or a line of text should display. The .NET Framework provides som mechanisms to control the amount of space used to display a string of text and how to align that string on its line.

To specify the amount of space used to display a string, you can use its placeholder in the Write() or the WriteLine() methods. To do this, in the placeholder, type the 0 or the incrementing number of the placeholder and its formatting character if necessary and if any. Then, type a comma followed by the number of characters equivalent to the desired width. Here are examples:

using System;

public class Exercise
{
    public static void Main()
    {
        var fullName = "Anselme Bogos";
        var age = 15;

        Console.WriteLine("Full Name: {0,20}", fullName);
        Console.WriteLine("Age:{0,14}", age;

        Console.WriteLine();
    }
}

This would produce:

Full Name:        Anselme Bogos
Age:            15

If the value you are displaying is a decimal number, you must call the ToString() method on the primitive variable. Here is an example:

using System;

public class Exercise
{
    public static void Main()
    {
        var fullName = "Anselme Bogos";
        var age = 15;
        var hSalary = 22.74;

        Console.WriteLine("Full Name: {0,20}", fullName);
        Console.WriteLine("Age:{0,14}", age.ToString());
        Console.WriteLine("Distance: {0:C,8}", hSalary.ToString());

        Console.WriteLine();
    }
}

This would produce:

Full Name:        Anselme Bogos
Age:            15
Distance: 22.74

The sign you provide for the width is very important. If it is positive, the line of text is aligned to the right. This should be your preferred alignment for numeric values. If the number is negative, then the text is aligned to the left.

Practical LearningPractical Learning: Formatting Data Display

  1. To format data display, change the document as follows:
    using static System.Console;
    
    namespace WaterDistributionCompany1
    {
        public class WaterDistributionCompany
        {
            private static Customer CreateAccount()
            {
                Customer client = new Customer();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Type the following pieces of information about the customer");
                Write("Account Number: ");
                client.AccountNumber = ReadLine();
                Write("First Name:     ");
                client.FirstName = ReadLine();
                Write("Last Name:      ");
                client.LastName = ReadLine();
    
                return client;
            }
    
            private static void Display(WaterBill bill)
            {
                WriteLine("Water Distribution Company");
                WriteLine("Bill Preparation");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0,18}", bill.InvoiceNumber);
                WriteLine("Customer Account #: {0,16}", bill.AccountNumber);
                WriteLine("-----------------------------------");
                WriteLine("Billing Days: {0,11}", bill.BillingDays);
                WriteLine("Counter Reading Start: {0}", bill.CounterReadingStart);
                WriteLine("Counter Reading End: {0,5}", bill.CounterReadingEnd);
                WriteLine("-----------------------------------");
                WriteLine("Total HCF: {0,17}", bill.TotalHCF.ToString("F"));
                WriteLine("Total Gallons: {0,16}", bill.TotalGallons.ToString("F"));
                WriteLine("First 15 HCF: {0,15}", bill.First15HCF.ToString("F"));
                WriteLine("Next 10 HCF: {0,15}", bill.Next10HCF.ToString("F"));
                WriteLine("Remaining HCF: {0,13}", bill.RemainingHCF.ToString("F"));
                WriteLine("Water Usage Charges: {0,8}", bill.WaterUsageCharges.ToString("F"));
                WriteLine("Water Usage Charges: {0,8}", bill.WaterUsageCharges.ToString("F"));
                WriteLine("Sewer Charges: {0,13}", bill.SewerCharges.ToString("F"));
                WriteLine("Storm Charges: {0,13}", bill.StormCharges.ToString("F"));
                WriteLine("Total Charges: {0,14}", bill.TotalCharges.ToString("F"));
                WriteLine("Local Taxes: {0,15}", bill.LocalTaxes.ToString("F"));
                WriteLine("State Taxes: {0,15}", bill.StateTaxes.ToString("F"));
                WriteLine("Amount Due: {0,18}", bill.AmountDue.ToString("C"));
                WriteLine("Late Amount Due: {0,13}", bill.LateAmountDue.ToString("C"));
                WriteLine("=====================================");
            }
    
            public static int Main()
            {
                WaterBill wb = new WaterBill();
    
                wb.InvoiceNumber = 384758;
    
                Customer cust = CreateAccount();
                wb.AccountNumber = cust.AccountNumber;
    
                Clear();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("----------------------------------------");
                WriteLine("Invoice #: {0,28}", wb.InvoiceNumber);
                WriteLine("Customer Account #: {0,19}", cust.AccountNumber);
                WriteLine("----------------------------------------");
                Write("Type the number of cycling days: ");
                wb.BillingDays = int.Parse(ReadLine());
                Write("Counter Reading Start:           ");
                wb.CounterReadingStart = int.Parse(ReadLine());
                Write("Counter Reading End:             ");
                wb.CounterReadingEnd = int.Parse(ReadLine());
    
                Clear();
    
                Display(wb);
    
                return 0;
            }
        }
    }
  2. To execute the application, on the main menu, click Debug -> Start Without Debugging
  3. Type some values as follows:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Type the following pieces of information about the customer
    Account Number: 2038-413-9680
    First Name:     Amidou
    Last Name:      Gomah
  4. Press Enter:
    Water Distribution Company
    Water Bill
    ----------------------------------------
    Invoice #:                       384758
    Customer Account #:       2038-413-9680
    ----------------------------------------
    Type the number of cycling days:
  5. Type some values as follows:
    Water Distribution Company
    Water Bill
    ----------------------------------------
    Invoice #:                       396980
    Customer Account #:       2038-413-9680
    ----------------------------------------
    Type the number of cycling days: 29
    Counter Reading Start:           137926
    Counter Reading End:             137931
  6. Press Enter
    Water Distribution Company
    Bill Preparation
    -----------------------------------
    Invoice #:             396980
    Customer Account #:    2038-413-9680
    -----------------------------------
    Billing Days:          29
    Counter Reading Start: 137926
    Counter Reading End: 137931
    -----------------------------------
    Total HCF:              5.00
    Total Gallons:          3740.25
    First 15 HCF:           18.06
    Next 10 HCF:            0.00
    Remaining HCF:          0.00
    Water Usage Charges:    18.06
    Water Usage Charges:    18.06
    Sewer Charges:          4.55
    Storm Charges:          0.05
    Total Charges:          22.66
    Local Taxes:            0.11
    State Taxes:            0.34
    Amount Due:             $23.11
    Late Amount Due:        $31.76
    =====================================
    Press any key to continue . . .
  7. Press Enter to close the DOS window and return to your programming environment

Converting an Object to String

The ToString() method of the Object class is virtual. This means that it is available to all classes that need that method, but each class must decide whether to override it or not. This also means that, if you want your class to provide its own version of a string, you should (must) override the Object.ToString() variable. To do this, in your class, create a body for the overridden version of the method. In the body, create an expression that produces a string and return a string or that expression.

Practical LearningPractical Learning: Converting to String

  1. Access the Customer.cs file
  2. To implement and use a ToString() method, change the file as follows:
    using System;
    
    namespace WaterDistributionCompany1
    {
        public class Customer : Object
        {
            public string AccountNumber { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
            public Customer(string acntNumber = "", string firstName = "", string lasName = "")
            {
                AccountNumber = acntNumber;
                FirstName = firstName;
                FirstName = lasName;
            }
    
            public override bool Equals(object obj)
            {
                Customer cust = (Customer)obj;
    
                if( AccountNumber == cust.AccountNumber )
                    return true;
    
                return false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
    
            public override string ToString()
            {
                return AccountNumber + " - " + FirstName + " " + LastName;
            }
        }
    }
  3. Access the WaterBill.cs file and change it as follows:
    namespace WaterDistributionCompany1
    {
        public class WaterBill
        {
            public int      InvoiceNumber       { get; set; }
            public Customer Customer            { get; set; }
            public int      BillingDays         { get; set; }
            public double   CounterReadingStart { get; set; }
            public double   CounterReadingEnd   { get; set; }
            public double   TotalHCF            { get { return CounterReadingEnd - CounterReadingStart; } }
            public double   TotalGallons        { get { return (CounterReadingEnd - CounterReadingStart) * 748.05; } }
    
            public double   First15HCF
            {
                get {
                    if (TotalHCF <= 15.00)
                    {
                        return TotalHCF * 3.612;
                        
                    }
                    else // if (TotalHCF <= 25.00)
                    {
                        return 15.00 * 3.612;
                    }
                }    
            }
    
            public double Next10HCF
            {
                get
                {
                    if (TotalHCF <= 15.00)
                    {
                        return 0.00;
                    }
                    else if (TotalHCF <= 25.00)
                    {
                        return (TotalHCF - 15.00) * 3.918;
                        
                    }
                    else
                    {
                        return 10.00 * 3.918;
                    }
                }
            }
            public double RemainingHCF
            {
                get
                {
                    if (TotalHCF <= 25.00)
                    {
                        return 0.00;
                    }
                    else
                    {
                        return (TotalHCF - 25.00) * 2.2763;
                    }
                }
            }
    
            public double WaterUsageCharges => First15HCF + Next10HCF + RemainingHCF;
            public double SewerCharges      => WaterUsageCharges * 0.252;
            public double StormCharges      => WaterUsageCharges * 0.0025;
            public double TotalCharges      => WaterUsageCharges + SewerCharges + StormCharges;
            public double LocalTaxes        => TotalCharges * 0.005;
            public double StateTaxes        => TotalCharges * 0.0152;
    	    public double AmountDue         => TotalCharges + LocalTaxes + StateTaxes;
            public double LateAmountDue     => AmountDue + 8.65;
        }
    }
  4. Access the WaterDistributionCompany.cs file and change it as follows:
    using static System.Console;
    
    namespace WaterDistributionCompany1
    {
        public class WaterDistributionCompany
        {
            private static Customer CreateAccount()
            {
                Customer client = new Customer();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("-----------------------------------");
                WriteLine("Type the following pieces of information about the customer");
                Write("Account Number: ");
                client.AccountNumber = ReadLine();
                Write("First Name:     ");
                client.FirstName = ReadLine();
                Write("Last Name:      ");
                client.LastName = ReadLine();
    
                return client;
            }
    
            private static void Display(WaterBill bill)
            {
                WriteLine("Water Distribution Company");
                WriteLine("Bill Preparation");
                WriteLine("-----------------------------------");
                WriteLine("Invoice #: {0,18}", bill.InvoiceNumber);
                WriteLine("Customer: {0,16}", bill.Customer);
                WriteLine("-----------------------------------");
                WriteLine("Billing Days: {0,11}", bill.BillingDays);
                WriteLine("Counter Reading Start: {0}", bill.CounterReadingStart);
                WriteLine("Counter Reading End: {0,5}", bill.CounterReadingEnd);
                WriteLine("-----------------------------------");
                WriteLine("Total HCF: {0,17}", bill.TotalHCF.ToString("F"));
                WriteLine("Total Gallons: {0,16}", bill.TotalGallons.ToString("F"));
                WriteLine("First 15 HCF: {0,15}", bill.First15HCF.ToString("F"));
                WriteLine("Next 10 HCF: {0,15}", bill.Next10HCF.ToString("F"));
                WriteLine("Remaining HCF: {0,13}", bill.RemainingHCF.ToString("F"));
                WriteLine("Water Usage Charges: {0,8}", bill.WaterUsageCharges.ToString("F"));
                WriteLine("Water Usage Charges: {0,8}", bill.WaterUsageCharges.ToString("F"));
                WriteLine("Sewer Charges: {0,13}", bill.SewerCharges.ToString("F"));
                WriteLine("Storm Charges: {0,13}", bill.StormCharges.ToString("F"));
                WriteLine("Total Charges: {0,14}", bill.TotalCharges.ToString("F"));
                WriteLine("Local Taxes: {0,15}", bill.LocalTaxes.ToString("F"));
                WriteLine("State Taxes: {0,15}", bill.StateTaxes.ToString("F"));
                WriteLine("Amount Due: {0,18}", bill.AmountDue.ToString("C"));
                WriteLine("Late Amount Due: {0,13}", bill.LateAmountDue.ToString("C"));
                WriteLine("=====================================");
            }
    
            public static int Main()
            {
                WaterBill wb = new WaterBill();
    
                wb.InvoiceNumber = 529794;
    
                wb.Customer = CreateAccount();
    
                Clear();
    
                WriteLine("Water Distribution Company");
                WriteLine("Water Bill");
                WriteLine("----------------------------------------");
                WriteLine("Invoice #: {0,28}", wb.InvoiceNumber);
                WriteLine("Customer Account #: {0,19}", wb.Customer);
                WriteLine("----------------------------------------");
                Write("Type the number of cycling days: ");
                wb.BillingDays = int.Parse(ReadLine());
                Write("Counter Reading Start:           ");
                wb.CounterReadingStart = int.Parse(ReadLine());
                Write("Counter Reading End:             ");
                wb.CounterReadingEnd = int.Parse(ReadLine());
    
                Clear();
    
                Display(wb);
    
                return 0;
            }
        }
    }
  5. To execute the application, on the main menu, click Debug -> Start Debugging
  6. When requested, type some values:
    Water Distribution Company
    Water Bill
    -----------------------------------
    Type the following pieces of information about the customer
    Account Number: 9279-570-8394
    First Name:     Thomas
    Last Name:      Stones
  7. Press Enter
    Water Distribution Company
    Water Bill
    ----------------------------------------
    Invoice #:                       529794
    Customer Account #: 9279-570-8394 - Thomas Stones
    ----------------------------------------
    Type the number of cycling days:
  8. Enter some values:
    Water Distribution Company
    Water Bill
    ----------------------------------------
    Invoice #:                       604482
    Customer Account #: 9279-570-8394 - Thomas Stones
    ----------------------------------------
    Type the number of cycling days: 30
    Counter Reading Start:           6268
    Counter Reading End:             6275
  9. Press Enter
    Water Distribution Company
    Bill Preparation
    -----------------------------------
    Invoice #:             604482
    Customer: 9279-570-8394 - Thomas Stones
    -----------------------------------
    Billing Days:          30
    Counter Reading Start: 6268
    Counter Reading End:   6275
    -----------------------------------
    Total HCF:              7.00
    Total Gallons:          5236.35
    First 15 HCF:           25.28
    Next 10 HCF:            0.00
    Remaining HCF:          0.00
    Water Usage Charges:    25.28
    Water Usage Charges:    25.28
    Sewer Charges:          6.37
    Storm Charges:          0.06
    Total Charges:          31.72
    Local Taxes:            0.16
    State Taxes:            0.48
    Amount Due:             $32.36
    Late Amount Due:        $41.01
    =====================================
    Press any key to continue . . .
  10. Press Enter to close the DOS window and return to your programming

Boxing and Un-Boxing

As mentioned already, all data types used in a C# program are "based on" an object called object. As introduced earlier, you can use this data type to declare a variable that would hold any type of value. Because this is some type of a "universal" data type, it can also be initialized with any value. Here are examples:

using System;

class Exercise
{
	static void Main()
	{
		object Number = 244;
		object Thing  = "Professor Kabba";

		Console.WriteLine(Number);
		Console.WriteLine(Thing);
	}
}

This would produce:

244
Professor Kabba

As you can see, when an object variable is initialized, the compiler finds out the type of value that was assigned to it. This is referred to as boxing. This mechanism is transparently done.

If you declare a variable using a primitive data type (int,double, etc), at one time, you may be interested in converting the value of that variable into an object. Here is an example:

using System;

class Exercise
{
    static int Main()
    {
    	int Number = 244;
	    object Thing  = Number;

    	Console.WriteLine(Number);
	    Console.WriteLine(Thing);
    	return 0;
    }
}

This would produce:

244
244

This operation is referred to as unboxing. As you can see, this operation is performed transparently. Boxing and unboxing make C# a very flexible and wonderful language.

Finalizing a Variable

While a constructor, created for each class, is used to instantiate a class. The object class provides the Finalize() method as a type of destructor.

The Console Object

The Text Color

By default, the text in the Console window is printed in gray. The Console class allows you to specify the color of a line of text you are displaying. To assist you, the class is equipped with a property named ForegroundColor. The value oh this property is a member of an enumeration named ConsoleColor:

public static ConsoleColor ForegroundColor { get; set; }

The members of the ConsoleColor enumeration are: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, and White.

The Highlighting Color

By default, the Console window is covered in black. When you decide to display some text in that window, the Console class allows you to highlight a line of text with a color. To assist you, the class is equipped with a property named BackgroundColor from the ConsoleColor property:

public static ConsoleColor BackgroundColor { get; set; }

Other Built-In Classes

The System namespace provides one of the largest definitions of classes of the .NET Framework, but it doesn't contain everything. The namespaces are contained in libraries called assemblies. The actual classes used in various applications are created and defined in these libraries. Before using a class, you must know the name of the assembly in which it is defined. You must also know the name of its namespace. These three pieces of information (the name of the class, the namespace in which it is defined, and the name of the assembly in which the namespace is contained) are very important.

Random Numbers

Introduction

Imagine you have a series of numbers, such these: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, and 20. Imagine you want to select one of these numbers, any of them. A number is referred to as random if it has been selected from a pool without a specific pattern to follow. For example, if you decide to select the value 17 from this list, if there was an exact reason that number was selected, then it is not considered random. In reality, it is difficult for a number to qualify as random. For this reason, most random numbers are referred to as pseudo-random.

Getting a Random Number

To support the ability to create or choose a random number, the .NET Framework provides the Random class. To start, you can declare a variable of this class, using one of its two constructors. Here is an example that uses the default constructor:

using System;

class Program
{
    static int Main()
    {
        Random rndNumber = new Random();
       
        return 0;
    }
}

After creating the variable, you can start getting numbers from it. To do this, you call the Next() method, which is overloaded in three versions. One of the versions of this method takes no argument and its syntax is:

public virtual int Next();

This method generates a randomly selected integer between 0 and the MinValue value of the int data type. Here is an example:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random();
        int    rndNumber = rndNumbers.Next();

        Console.WriteLine("Number: {0}", rndNumber);
       
        return 0;
    }
}

Here is an example of running the program:

Number: 1369872590
Press any key to continue . . .

In the same way, you can call this version of the Next() method repeatedly to get random. Here is an example:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random();
        int rndNumber = 0;

        for (int nbr = 1; nbr < 9; nbr++)
        {
            rndNumber = rndNumbers.Next();
            Console.WriteLine("Number: {0}", rndNumber);
        }

        return 0;
    }
}

Here is an example of running the program:

Number: 1924504148
Number: 1257846191
Number: 424740120
Number: 1009211682
Number: 544356245
Number: 708951978
Number: 759684741
Number: 1325535324
Press any key to continue . . .

The Seed of a Random Number

Consider the following program:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random();
        int rndNumber = rndNumbers.Next();

        Console.WriteLine("Number: {0}", rndNumber);

        return 0;
    }
}

Here is an example of running the program:

Number: 573991745
Press any key to continue . . .

Here is another example of running the same program:

Number: 334223329
Press any key to continue . . .

Notice that the numbers generated are different. When creating a program that repeatedly gets a series of random numbers, you may (or may not) want the Random class to generate the same number over and over again. A seed is a constant value that controls whether a random generation would produce the same result every time it occurs. For example, using a seed, you can impose it upon the Random class to generate the same number every time the Next() method is called. To support the ability to use a seed, the Random class is equipped with a second constructor whose syntax is:

public Random(int Seed);

Based on this, to specify a seed, when declaring a Random variable, pass a constant integer to the constructor. Here is an example:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random(20);
        int rndNumber = rndNumbers.Next();

        Console.WriteLine("Number: {0}", rndNumber);

        return 0;
    }
}

Here is one example of running the program:

Number: 375271809
Press any key to continue . . .

Here is another example of running the same program:

Number: 375271809
Press any key to continue . . .

Notice that the numbers are the same. Consider this program also:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random(20);
        int rndNumber = 0;


        for (int nbr = 1; nbr < 5; nbr++)
        {
            rndNumber = rndNumbers.Next();
            Console.WriteLine("Number: {0}", rndNumber);
        }

        return 0;
    }
}

Here is one example of running the program:

Number: 375271809
Number: 1472524622
Number: 1605850688
Number: 1776011503
Press any key to continue . . .

Here is another example of running the same program:

Number: 375271809
Number: 1472524622
Number: 1605850688
Number: 1776011503
Press any key to continue . . .

Notice that the sequences are the same. In both cases, this indicates that, if you specify a seed, the Random class would generate the same number or the same sequence of numbers.

Generating Random Numbers in a Range of Numbers

So far, we have been using any number that would fit an integer. In some assignments, you may want to restrict the range of numbers that can be extracted. Fortunately, the Random class allows this. Using the Random class, you can generate random positive numbers up to a maximum of your choice. To support this, the Random class is equipped with another version of the Next() method whose syntax is:

public virtual int Next(int maxValue);

The argument to pass to the method determines the highest integer that can be generated by the Next() method. The method returns an integer. Here is an example that generates random numbers from 0 to 20:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random();
        int rndNumber = 0;


        for (int nbr = 1; nbr < 9; nbr++)
        {
            rndNumber = rndNumbers.Next(20);
            Console.WriteLine("Number: {0}", rndNumber);
        }

        return 0;
    }
}

Here is an example of running the program:

Number: 1
Number: 7
Number: 1
Number: 16
Number: 14
Number: 19
Number: 3
Number: 1
Press any key to continue . . .

The above version of the Next() method generates numbers starting at 0. If you want, you can specify the minimum and the maximum range of numbers that the Next() method must work with. To support this, the Random class is equipped with one more version of this method and that takes two arguments. Its syntax is:

public virtual int Next(int minValue, int maxValue);

The first argument specifies the lowest value that can come from the range. The second argument holds the highest value that the Next() method can generate. Therefore, the method would operate between both values. Here is an example that generates random numbers from 6 to 18:

using System;

class Program
{
    static int Main()
    {
        Random rndNumbers = new Random();
        int rndNumber = 0;


        for (int nbr = 1; nbr < 9; nbr++)
        {
            rndNumber = rndNumbers.Next(6, 18);
            Console.WriteLine("Number: {0}", rndNumber);
        }

        return 0;
    }
}

Here is an example of running the program:

Number: 17
Number: 9
Number: 8
Number: 15
Number: 10
Number: 9
Number: 13
Number: 11
Press any key to continue . . .

Notice that the numbers are between 6 and 18.

Message Boxes

One of the objects you can use from the .NET Framework is a message box. A message box is a rectangular object that displays a message and can have some options. The message box is defined in a static class named MessageBox. The MessageBox class is created in the System.Windows.Forms namespace that is a member of the System.Windows.Forms.dll assembly..

The MessageBox class is equipped with a method named Show that is used to hold the message to present to the user. The MessageBox.Show() method is overloaded with different versions to support various options. The simplest version takes only one argument as a string, which is the message to present to the user. The syntax of that version is:

public static DialogResult Show(string text);

To use this version of the MessageBox.Show(), put the desired message with double-quotes to the parentheses. Here is an example:

MessageBox.Show("Welcome to the wonderful world of C# programming!");

You can then execute the application. If you create a console application and you want to use a message box, make sure you add a reference to the System.Windows.Forms.dll library in your project.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2008-2019, FunctionX Next